littletable 是我多年前编写的一个精简的 CSV 包装器。 littletable 中的表格是对象列表,带有一些用于过滤、连接、透视的辅助方法,以及 CSV、JSON 和固定格式数据的轻松导入/导出。与 pandas 一样,它有助于数据导入/导出,但不具备 pandas 所具有的所有其他数值分析功能。它还将所有数据作为 Python 对象列表保存在内存中,因此它不会像 pandas 那样处理数百万行。但如果您的需求不大,那么使用 littletable 可能会缩短学习曲线。
要将您的初始原始数据加载到 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")
(也可以创建唯一索引,但在这种情况下,您的原始输入中存在具有相同 id 的重复值。)
表可以按一个或多个属性进行分组,然后可以将每组记录传递给一个函数,以给出该组的聚合值。在您的情况下,您希望为每个产品 id 收集所有 altids。
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'}
现在我们将把这个表与id 上的原始tt 表连接起来,并折叠重复项:
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)))