python:合并具有公共字段的行

时间:2014-04-17 20:57:45

标签: python

我有一个类似这样的数据:

apple   873     8695    913     1084
apple   873     8695    3953    4498
apple   873     8695    4549    8639
peach   22087   23527   22956   23034
peach   22087   23527   22799   22898
peach   22087   23527   22634   22722
peach   22087   23527   22456   22553
orange  10731   23193   22799   22932
orange  10731   23193   22634   22722
orange  10731   23193   22084   22553
orange  10731   23193   21965   22023

正如您所看到的,对于每种水果,第2和第3列是相同的,但第4和第5列是不同的。我想编写一个python脚本来合并这些行,并列出以逗号分隔的一行中的第4和第5列中的所有内容。

这样的事情:

apple   873     8695    913,1084,3953,4498,4549,8639
peach   22087   23527   22956,23034,22799,22898,22634,22722,22456,22533
orange  10731   23193   22799,22932,22634,22722,22084,22553,21965,22023

有人可以帮我解决这个问题吗?我有一个非常复杂的数据集,我简化为这种格式。现在我需要做的就是这一步。似乎解决方案将非常简单,但我甚至不确定如何搜索如何执行此操作。因此我的头衔听起来也很尴尬。我很感激你的帮助。

3 个答案:

答案 0 :(得分:1)

这是使用groupby的绝佳机会(请参阅How do I use Python's itertools.groupby()?以获得很好的解释)。

基本上你可以将你的文件读入带有readlines()的字符串列表中,并将它们与你在那里看到的lambda函数分组,这是它们的三个第一个元素。 (或一个或两个)。然后,您将获得一组可以迭代的条目,并将它们的最后一个元素(第4和第5列)追加到您打印出的列表中(使用组中元素的开头)。鉴于您的示例数据存储在file.txt中:

from itertools import groupby

f = open('file.txt')

lines = f.readlines()

for key, group in groupby(lines, lambda x: x.split()[0:3]):
    restelms = []
    for elm in group:
        splitelm = elm.split()
        for subelm in splitelm[3:]:
            restelms.append(subelm)

    print '\t'.join(key + [','.join(restelms)])

f.close()

答案 1 :(得分:0)

假设您的数据文件位于 filename.txt

from collections import defaultdict
d = defaultdict(list)
for line in open('filename.txt'):
    tokens = line.split()
    d[tuple(tokens[:3])].extend(tokens[3:])

for k in sorted(d.keys()):
    v = d[k]
    print('{}\t{}\t{}\t{}'.format(k[0],k[1],k[2],','.join(v)))

输出

apple   873     8695    913,1084,3953,4498,4549,8639
orange  10731   23193   22799,22932,22634,22722,22084,22553,21965,22023
peach   22087   23527   22956,23034,22799,22898,22634,22722,22456,22553

如果要将数据输出到文件 output.txt ,请将最后三行替换为:

with open('output.txt','w') as outfile:
    for k in sorted(d.keys()):
        v = d[k]
        print('{}\t{}\t{}\t{}'.format(k[0],k[1],k[2],','.join(v)),file=outfile)

答案 2 :(得分:0)

from itertools import groupby
from operator import itemgetter

txt = dedent("""\
    apple   873     8695    913     1084
    apple   873     8695    3953    4498
    apple   873     8695    4549    8639
    peach   22087   23527   22956   23034
    peach   22087   23527   22799   22898
    peach   22087   23527   22634   22722
    peach   22087   23527   22456   22553
    orange  10731   23193   22799   22932
    orange  10731   23193   22634   22722
    orange  10731   23193   22084   22553
    orange  10731   23193   21965   22023
""")

data = (row.split() for row in txt.splitlines())
data = [("\t".join(row[:3]), ",".join(row[3:])) for row in data]

output = [
    label + "\t" + ",".join(row[1] for row in rows)
    for label,rows in groupby(data, itemgetter(0))
]

print("\n".join(output))

结果

apple   873     8695    913,1084,3953,4498,4549,8639
peach   22087   23527   22956,23034,22799,22898,22634,22722,22456,22553
orange  10731   23193   22799,22932,22634,22722,22084,22553,21965,22023