Вопрос по csv, python – Объединение всех строк файла CSV с одинаковым значением первого столбца в Python

2

У меня есть файл CSV, который выглядит примерно так:

['Name1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '+']
['Name1', '', '', '', '', '', 'b', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
['Name2', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'a', '']
['Name3', '', '', '', '', '+', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']

Теперь мне нужен способ объединить все строки с одинаковым именем первого столбца в один столбец, например:

['Name1', '', '', '', '', '', 'b', '', '', '', '', '', '', '', '', '', '', '', '', '', '+']
['Name2', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'a', '']
['Name3', '', '', '', '', '+', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']

Я могу придумать способ сделать это, отсортировав CSV, а затем пройдя по каждой строке и столбцу и сравнив каждое значение, но, вероятно, должен быть более простой способ сделать это.

Есть идеи?

Вы, вероятно, должны быть более точными в том, чтоjoin следует сделать. moooeeeep
Это звучит как самый логичный способ сделать. eumiro
@moooeeeep: Хорошо, я хочу присоединиться к ним, чтобы они были как во второй части примера. jbssm
@CharlesBrunet: Нет, для того же имени значение может появиться в одном из других столбцов только один раз для каждого столбца. jbssm
Может ли один и тот же столбец присутствовать в двух строках с одинаковым первым значением? Что вы хотите сделать в этом случае? Charles Brunet

Ваш Ответ

3   ответа
3

t = [ 
['Name1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '+'],
['Name1', '', '', '', '', '', 'b', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
['Name2', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'a', ''],
['Name3', '', '', '', '', '+', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''] 
]

from itertools import groupby

# TODO: if you need to speed things up you can use operator.itemgetter
# for both sorting and grouping
for name, rows in groupby(sorted(t), lambda x:x[0]):
    print join_rows(rows)

Очевидно, что вы осуществили объединение в отдельной функции. Например, вот так:

def join_rows(rows):
    def join_tuple(tup):
        for x in tup:
            if x: 
                return x
        else:
            return ''
    return [join_tuple(x) for x in zip(*rows)]
@SimeonVisser спасибо за эту заметку!
@moooeeeep не использоватьsorted без ключа это ненужное время выполнения.
Это не работает. Это join_rows функция из какой-то библиотеки или что-то, что я должен написать отдельно от кода? jbssm
Обратите внимание, чтоt должен быть заказан по имени, чтобы это работало.
@jbssm thejoin_rows является точкой входа для вашего кода, это для вас, чтобы написать;)
1
def merge_rows(row1, row2):
    # merge two rows with the same name
    merged_row = ...
    return merged_row

r1 = ['Name1', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '+']
r2 = ['Name1', '', '', '', '', '', 'b', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
r3 = ['Name2', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'a', '']
r4 = ['Name3', '', '', '', '', '+', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
rows = [r1, r2, r3, r4]
data = {}
for row in rows:
    name = row[0]
    if name in data:
        data[name] = merge_rows(row, data[name])
    else:
        data[name] = row

data где каждый ключ этого словаря - это имя, а соответствующее значение - эта строка. Теперь вы можете записать эти данные в файл CSV.

Спасибо. Я написал это, и он отлично работает. jbssm
Привет и спасибо, Симеон: я не понимаю, что происходит в части merged_row. Где хранится предыдущая строка (или строки) с тем же именем, чтобы я мог их объединить? jbssm
Текущая строка, которую вы обрабатываете,row а другойdata[name], Строка вdata[name] является либо предыдущей строкой с этим именем, либо результатом одного или нескольких слияний строк с этим именем. Таким образом, вам нужно только написать код, который определяет, как объединить две строки с одинаковым именем. Если вы напишите этот код дляmerged_row затем он будет многократно объединять строки (даже если есть три или более строк с одинаковым именем).
Я обновил код, чтобы он немного очистился. Все, что вам нужно сделать, это написатьmerge_rows указать, как две строки с одинаковым именем должны быть объединены.
0

defaultdict:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> _ = [d[i[0]].append(z) for i in t for z in i[1:]]
>>> d['Name1']
['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '+', '', '', '', '', '', 'b', '', '', '', '', '', '', '', '', '', '', '', '', '', '']

Затем присоединитесь к вашей колонке

Похожие вопросы