littletable - это тонкая CSV-оболочка, которую я написал несколько лет назад. Таблицы в littletable представляют собой списки объектов с некоторыми вспомогательными методами для фильтрации, объединения, поворота, а также простым импортом / экспортом данных CSV, JSON и данных фиксированного формата. Как и pandas, он помогает с импортом / экспортом данных, но не имеет всех других числовых аналитических функций, которые есть у pandas. Он также хранит все данные в памяти в виде списка объектов Python, поэтому он не будет обрабатывать миллионы строк, как это делает панда. Но если ваши потребности скромны, то, возможно, вам понадобится более короткая кривая обучения для работы с littletable.
Загрузка ваших исходных необработанных данных в небольшую таблицу начинается с:
import littletable as lt
data = open('raw_data.csv')
tt = lt.Table().csv_import(data, fieldnames="id name altid".split(), delimiter=';')
(Если во входном файле есть строка заголовка, csv_import
будет использовать это и не потребует, чтобы вы указали fieldnames
.)
Распечатка строк выглядит как перебор списка:
for row in tt:
print(row)
печать:
{'name': 'product1', 'altid': '58', 'id': '33'}
{'name': 'product2', 'altid': '95', 'id': '43'}
{'name': 'product1', 'altid': '62', 'id': '33'}
{'name': 'product3', 'altid': '11', 'id': '68'}
{'name': 'product2', 'altid': '99', 'id': '43'}
Поскольку мы будем группировать и объединять атрибуты id
, мы добавим индекс:
tt.create_index("id")
(Также могут быть созданы уникальные индексы, но в этом случае в исходном вводе есть повторяющиеся значения с тем же идентификатором.)
Таблицы могут быть сгруппированы по одному или нескольким атрибутам, а затем каждая группа записей может быть передана в функцию, чтобы получить совокупное значение для этой группы. В вашем случае вам нужны все собранные altids
для каждого продукта id
.
def aggregate_altids(rows):
return ' '.join(set(row.altid for row in rows if row.altid != row.id))
grouped_altids = tt.groupby("id", altids=aggregate_altids)
for row in grouped_altids:
print(row)
Дает:
{'altids': '62 58', 'id': '33'}
{'altids': '99 95', 'id': '43'}
{'altids': '11', 'id': '68'}
Теперь мы объединяем эту таблицу с исходной таблицей tt
на id
и раскладываем дубликаты:
tt2 = (grouped_altids.join_on('id') + tt)().unique("id")
и распечатать результаты:
for row in tt2:
print("{id};{name};{alt_ids}".format_map(vars(row)))
Предоставление:
33;product1;58 62
43;product2;95 99
68;product3;11
Общий код без отладки выглядит так:
# import
import littletable as lt
with open('raw_data.csv') as data:
tt = lt.Table().csv_import(data, fieldnames="id name altid".split(), delimiter=';')
tt.create_index("id")
# group
def aggregate_altids(rows):
return ' '.join(set(row.altid for row in rows if row.altid != row.id))
grouped_altids = tt.groupby("id", alt_ids=aggregate_altids)
# join, dedupe, and sort
tt2 = (grouped_altids.join_on('id') + tt)().unique("id").sort("id")
# output
for row in tt2:
print("{id};{name};{alt_ids}".format_map(vars(row)))