【问题标题】:More efficient way to retrieve first occurrence of every unique value from a csv column in Python从 Python 中的 csv 列中检索每个唯一值的第一次出现的更有效方法
【发布时间】:2013-03-19 20:35:31
【问题描述】:

给我的一个大 csv 文件有一个大的航班数据表。我编写的一个用于帮助解析它的函数会遍历 Flight ID 列,然后返回一个字典,其中包含每个唯一 Flight ID 的索引和值(按首次出现的顺序)。

字典 = { 索引:FID, ... }

这是对旧功能的快速调整,不需要担心列中的 FID 重复(几十万行之后...)。

现在,我让它迭代并按顺序比较每个值。如果一个值等于它后面的值,它会跳过它。如果下一个值不同,它将值存储在字典中。我将其更改为现在还检查该值之前是否已经出现,如果是,则跳过它。
这是我的代码:

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 处理这么多显然不是一个好主意,但我现在坚持下去。

有没有更高效的方法来编写这个函数?

【问题讨论】:

  • 旁白:我不确定您的命名法决定——无论是在这里还是在前面的问题中——对你的专业服务有多大,尽管显然你的里程可能会有所不同。无论如何,这让我决定不花时间指出某些问题:生命太短暂了。 (提示:.values() 返回什么?为什么用它进行会员测试是个坏主意?)
  • 不知道我的牧师在 Stackoverflow 上,下次我会记住的。

标签: python algorithm iteration


【解决方案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 

【讨论】:

  • 我明白你的意思,但我搜索的是值,而不是键。
  • 哎呀好点 - 将值保存为 set 并进行测试怎么样?
  • 会试一试,还有一个数据库。无论哪个我先找到时间。感谢您指出这一点,脑筋急转弯很容易错过琐碎的事情。
【解决方案2】:

您实际上是在寻找数据库。数据库正是为大型数据集上的此类操作而制作的。使用 CSV module 一次解析整个 CSV 并将它们发送到数据库中,比将它们存储在字典中并针对整个字典运行检查要快得多。

*large* python dictionary with persistence storage for quick look-ups

【讨论】:

    【解决方案3】:

    要直接回答您的问题,您应该能够使用 dict 理解和 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'}
    

    我认为这可以稍微调整一下——我对两次复习字典不太高兴。但无论如何,我认为 dict 理解非常有效。此外,groupby 假设您的键是有序的——也就是说,它假设所有 'a 的索引都组合在一起,这在您的情况下似乎是正确的。

    【讨论】:

    • 在上一个问题中有一个小例子来说明这里的数据是什么样子的:link 注意,在这种情况下,所有空格都有数据。
    猜你喜欢
    • 1970-01-01
    • 2013-02-28
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多