在Python中更高效地从CSV列中获取每个唯一值的首次出现
我收到了一份很大的CSV文件,里面有一大堆航班数据。我写了一个函数来帮助解析这些数据,它会遍历航班ID这一列,然后返回一个字典,里面包含每个独特的航班ID及其首次出现的位置和对应的值。
字典的格式是这样的:{ 索引: 航班ID, ... }
这个函数是对一个旧函数的快速调整,旧函数不需要担心航班ID在这一列中重复(几百万行之后...)。
现在,我的函数是逐个比较每个值。如果一个值和它后面的值相等,就跳过它。如果下一个值不同,就把这个值存入字典。我还改进了代码,现在它会检查这个值之前是否出现过,如果出现过,就跳过它。
这是我的代码:
def DiscoverEarliestIndex(self, number):
finaldata = {}
columnvalues = self.column(number)
columnenum = {}
for a, b in enumerate(columnvalues):
columnenum[a] = b
i = 0
while i < (len(columnvalues) - 1):
next = columnenum[i+1]
if columnvalues[i] == next:
i += 1
else:
if next in finaldata.values():
i += 1
continue
else:
finaldata[i+1]= next
i += 1
else:
return finaldata
这个方法效率很低,随着字典的增大,速度会变得很慢。这一列有520万行,所以用Python处理这么多数据显然不是个好主意,但我现在只能这样做。
有没有更高效的方法来写这个函数呢?
3 个回答
1
直接回答你的问题,你可以使用字典推导和itertools模块来实现这个功能。
>>> import itertools as it
>>> data = {1: 'a', 2: 'a', 3: 'c', 4: 'c', 5:'d' }
>>> grouped_shit = {k: list(v) for (k,v) in it.groupby(data.iteritems(), lambda (_,v): v)}
>>> good_shit = {v[0][0]: k for (k, v) in grouped_shit.iteritems()}
>>> good_shit
{1: 'a', 3: 'c', 5: 'd'}
我觉得这个方法可以稍微调整一下——我不是特别喜欢对字典进行两次遍历。不过,总的来说,我认为字典推导的效率还是挺高的。另外,groupby
这个函数假设你的键是有顺序的——也就是说,它假设所有的'a'的索引是聚在一起的,这在你的情况中似乎是成立的。
1
你其实是在寻找一个数据库。数据库就是为了处理大数据集而设计的。一次性用CSV模块解析整个CSV文件,然后把数据放进数据库,这样会比把数据存到字典里再去检查字典中的每一项快得多。
1
if next in thegoodshit.values():
你可能遇到的问题就是你在这里做的事情:
- 创建一个列表
- 在这个列表中查找
也许你可以使用一个 set
来存储这些值,然后在里面查找 - 大概可以这样做:
while i < (len(columnvalues) - 1):
next = columnenum[i+1]
if columnvalues[i] == next:
i += 1
else:
if next in searchable_data:
i += 1
continue
else:
finaldata[i+1]= next
searchable_data.add(next)
i += 1
else:
return finaldata