【问题标题】:merging records in python or numpy在 python 或 numpy 中合并记录
【发布时间】:2012-01-27 00:07:05
【问题描述】:

我有一个 csv 文件,其中第一列包含标识符,第二列包含相关数据。标识符被复制任意次数,所以文件看起来像这样。
数据1,123
数据1,345
数据1,432
数据2,654
数据2,431
数据3,947
数据3,673

我想合并记录,为每个标识符生成一条记录并获取。
数据1,123,345,432
数据2,654,431
数据3,947,673

在 python 或 numpy 中是否有有效的方法来执行此操作?由于重复键,字典似乎已失效。目前,我在列表列表中有这些行,然后循环遍历并测试列表中索引 0 处的前一个值的身份,但这非常笨拙。感谢您的帮助。

【问题讨论】:

  • “由于重复的键,字典似乎已失效”我不确定我是否理解为什么这是一个问题。带有值列表的字典不起作用吗?就像在您的示例中一样,很容易做出以{'data1': [123, 345, 432], 'data2': [654, 431], 'data3': [947, 673]} 结尾的东西

标签: python merge numpy


【解决方案1】:

如果第一列中给定值的所有实例都是连续的,那么这是itertools.groupby 的完美用例。它会像这样使用:

from itertools import groupby
from csv import reader
from operator import itemgetter

with open(filename) as f:
     for k, g in groupby(reader(f), key=itemgetter(0)):
         record = ','.join(k, *g)
         # do something with record, e.g. write to a file

(你可能需要','.join(k, *list(g)) 或类似的东西,我暂时无法测试)

【讨论】:

  • 非常感谢。我不知道 * 在这种情况下的作用,但是如果我在加入 g 变量时将其串起来,则这种方法有效。我先让下面的那个工作,然后继续。
  • * 是参数解包运算符,它将列表转换为函数参数。所以f(x, *y) 等价于f(x, y[0], y[1], ...)
【解决方案2】:

如果值是列表,您可以使用字典。 collections 模块中的 defaultdict 对此非常有用。

【讨论】:

    【解决方案3】:

    这就是你如何使用 defaultdict 来做你需要的事情,

    import csv
    from collections import defaultdict
    
    records = defaultdict(list)
    for key, value in csv.reader(open(filename)):
        records[key].append(int(value))
    
    for key in records:
        print key, records[key]
    

    结果,

    data1 [123, 345, 432]
    data3 [947, 673]
    data2 [654, 431]
    

    【讨论】:

    • 太好了,谢谢(也感谢 MRAB)。这完成了工作,脚本正在运行。
    猜你喜欢
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    相关资源
    最近更新 更多