在Python中更高效地从CSV列中获取每个唯一值的首次出现

0 投票
3 回答
690 浏览
提问于 2025-04-17 19:40

我收到了一份很大的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文件,然后把数据放进数据库,这样会比把数据存到字典里再去检查字典中的每一项快得多。

*大型* Python字典,带持久存储以便快速查找

1
if next in thegoodshit.values():   

你可能遇到的问题就是你在这里做的事情:

  1. 创建一个列表
  2. 在这个列表中查找

也许你可以使用一个 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 

撰写回答