Python - 选择满足特定条件的所有行值一次

时间:2014-10-07 23:52:34

标签: python csv python-3.x deduplication

我的表单设置了以下字段:日期时间,ID和地址。此表单自动为每个条目分配一个唯一的id字符串(U_ID),然后将此数据输出到带有标题和行的csv,如下所示:

Date Time       ID    U_ID     Address
9/12/13 12:07   13    adfasd   1345 Wilson Way
9/12/13 13:45   8     jklj     1456 Jackson Hollow
9/13/13 14:55   13    klidh    1345 Wilson Way
9/13/13 15:00   8     ikodl    1456 Jackson Hollow

我正在寻找一种通过Python脚本删除具有相同ID的重复提交的方法,同时保留行中的其余数据。理想情况下,我希望只保留与csv文件中的ID相关联的第一个条目。

输出应该如下所示:

Date Time       ID    U_ID     Address
9/12/13 12:07   13    adfasd   1345 Wilson Way
9/12/13 13:45   8     jklj     1456 Jackson Hollow

到目前为止,我一直坚持:

import csv

with open('/Users/user/Desktop/test.csv', 'rb') as f:
r = csv.reader(f)
headers = r.next()
rows = [(Date Time, ID, U_ID, Address) for Date Time, ID, U_ID, Address in r]
clean = [row for row in rows if row[1] != '#N/A']
clean2 = list(set(row[1]))

这给了我一个只包含ID唯一值的列表,但我不知道如何恢复与这些值的行相关的所有其他数据。

如上所述,如果我也可以获得最早的提交,那将是非常好的,但老实说,ID的任何独特提交都应该这样做。

感谢阅读!

2 个答案:

答案 0 :(得分:0)

看一下pandas,你就是这样做的:

import pandas as pd

pd.read_table('test.csv')\
  .drop_duplicates(subset=['ID'])\
  .to_csv('output.csv', index=None, sep='\t')

<强> output.csv

Date    Time    ID  U_ID    Address
9/12/13 12:07   13  adfasd  1345 Wilson Way
9/12/13 13:45   8   jklj    1456 Jackson Hollow

答案 1 :(得分:0)

首先,上面的文件是固定宽度的文件,而不是csv。使用固定宽度的字符串索引。

最简单的方法就是将独特的部分存储在一个集合中,这样您就可以快速检查它们之前是否已经被人看到过。

path = '/Users/user/Desktop/test.csv'
already_read = set()
with open(path, 'rb') as f:
    header = f.readline().strip()
    print header
    for line in f:
        unique_part = line[17:].strip()
        if unique_part in already_read:
            continue
        already_read.add(unique_part)
        print line.strip()

如果文件是TSV(制表符分隔文件),则可以使用split而不是原始索引:

path = '/Users/user/Desktop/test.csv'
already_read = set()
with open(path, 'rb') as f:
    header = f.readline().strip()
    print header
    for line in f:
        unique_part = '\t'.join(line.strip().split('\t')[2:])
        if unique_part in already_read:
            continue
        already_read.add(unique_part)
        print line.strip()