通过Python迭代基于记录版本的csv记录

时间:2018-02-22 20:30:09

标签: python

我有一个csv文件,它有一个primary_id字段和一个版本字段,它看起来像这样:  

ful_id                               version    xs  at_grade    date
000c1a6c-1f1c-45a6-a70d-f3555f7dd980    3       123   yes      20171003
000c1a6c-1f1c-45a6-a70d-f3555f7dd980    1       12    no       20170206
034c1a6c-4f1c-aa36-a70d-f2245f7rr342    1       334   yes      20150302
00dc5fec-ddb8-45fa-9c86-77e09ff590a9    1       556   yes      20170201
000c1a6c-1f1c-45a6-a70d-f3555f7dd980    2       123   no       20170206

编辑这是实际数据的样子,再添加106列数据和20,000条记录

较大的版本号是该记录的最新版本。我很难想到基于版本获取最新记录并将其转储到字典中的逻辑。我将信息从csv拉入到空白列表,但如果有人能给我一些关于前进逻辑的指导,我将不胜感激

import csv
from collections import defaultdict

reader = csv.DictReader(open('rpm_inv.csv', 'rb'))
allData = list(reader)
dict_list = []
for line in allData:
   dict_list.append(line)
pprint.pprint(dict_list)

2 个答案:

答案 0 :(得分:1)

我不确定您希望输出看起来如何,但只要您不反对pandas,这可能至少指向正确的方向。

import pandas as pd

df = pd.read_csv('rpm_inv.csv', header=True)

by_version = df.groupby('Version')

latest = by_version.max()
# To put it into a dictionary of {version:ID}
{v:row['ID'] for v, row in latest.iterrows()}

答案 1 :(得分:0)

不需要任何花哨的东西。

  • defaultdict包含在Python的标准库中。它是一本改进的字典。我在这里使用它是因为它不需要初始化词典中的条目。这意味着我可以编写result[id] = max(result[id], version)。如果id没有条目,那么defaultdict会创建一个并将version放入其中(因为很明显这将是最大值)。
  • 我读取输入文件中的行,一次一个,丢弃结束行和空格,分割逗号,然后使用mapint函数应用于每个字符串制造。
  • 我忽略文件中的第一行只是阅读它并将其内容分配给我任意称为ignore的变量。
  • 最后,为了使结果更容易理解,我对字典中的键进行排序,并按顺序显示它的内容。
>>> from collections import defaultdict
>>> result = defaultdict(int)
>>> with open('to_dict.txt') as input:
...     ignore = input.readline()
...     for line in input:
...         id, version = map(int, line.strip().replace(' ', '').split(','))
...         result[id] = max(result[id], version)
...         

>>> ids = list(result.keys())
>>> ids.sort()
>>> for id in ids:
...     id, result[id]
...     
(3, 1)
(11, 3)
(20, 2)
(400, 2)

编辑:根据我的估计,使用那么多数据会成为一个不同的问题,使用大熊猫进行更好的处理。

我已将df.groupby(['ful_id']).version.idxmax()位用于展示我所做的事情。我在ful_id上进行分组,然后使用version一步请求idxmax的最大值和最大值的索引。虽然pandas将其显示为一个双列表,但结果实际上是一个整数列表,我可以用它来从数据框中选择行。

我对df.iloc[df.groupby(['ful_id']).version.idxmax(),:]的处理方式。这里df.groupby(['ful_id']).version.idxmax()部分标识行,:部分标识列,即所有列。

感谢您提出一个有趣的问题!

>>> import pandas as pd
>>> df = pd.read_csv('different.csv', sep='\s+')
>>> df
                                 ful_id  version   xs at_grade      date
0  000c1a6c-1f1c-45a6-a70d-f3555f7dd980        3  123      yes  20171003
1  000c1a6c-1f1c-45a6-a70d-f3555f7dd980        1   12       no  20170206
2  034c1a6c-4f1c-aa36-a70d-f2245f7rr342        1  334      yes  20150302
3  00dc5fec-ddb8-45fa-9c86-77e09ff590a9        1  556      yes  20170201
4  000c1a6c-1f1c-45a6-a70d-f3555f7dd980        2  123       no  20170206
>>> df.groupby(['ful_id']).version.idxmax()
ful_id
000c1a6c-1f1c-45a6-a70d-f3555f7dd980    0
00dc5fec-ddb8-45fa-9c86-77e09ff590a9    3
034c1a6c-4f1c-aa36-a70d-f2245f7rr342    2
Name: version, dtype: int64
>>> new_df = df.iloc[df.groupby(['ful_id']).version.idxmax(),:]
>>> new_df
                                 ful_id  version   xs at_grade      date
0  000c1a6c-1f1c-45a6-a70d-f3555f7dd980        3  123      yes  20171003
3  00dc5fec-ddb8-45fa-9c86-77e09ff590a9        1  556      yes  20170201
2  034c1a6c-4f1c-aa36-a70d-f2245f7rr342        1  334      yes  20150302