【问题标题】:Time complexity vs memory usage in pandas using large datasets使用大型数据集的 pandas 的时间复杂度与内存使用情况
【发布时间】:2019-12-14 08:55:30
【问题描述】:

我想知道在 pandas 数据框中创建列的最有效方法是哪种方法,如果给定列表中存在 id_row 将返回 1 或 0。

我目前正在使用 lambda 函数来应用结果。我的问题是它需要很长时间,因为我的数据框大约有 2M 行,并且它检查的列表在 200k 到 100k 之间。如果我没记错的话,这是二次时间(不过我真的不确定),在这种情况下,它的运行速度真的很慢,给出了对象的大小。

最糟糕的是,我必须为 100 多个其他(不同的)数据帧重复这段代码。

函数如下:

 lst_to_add = [1,2,3.......,n] 
 df_table['TEST'] = df_table['id_row'].apply(lambda x : 1  if x i lst_to_add else 0)

我想知道如何使代码(方式)更有效。 我可能想到了一个使用递归函数的“分而治之”的解决方案,但我真的很愿意接受任何建议。

最后一件事。我也有记忆的限制,因此我更喜欢一种比其他方法花费更多时间但内存更少的方法(如果我有选择的话)。

【问题讨论】:

    标签: python pandas time-complexity


    【解决方案1】:

    就时间复杂性而言,您的list 应该是set,这将使您的 O(M*N) 解决方案 O(N),因为集合成员资格测试是恒定时间而不是线性时间(就像列表一样)。然后,使用内置方法.isin

    lst_to_add = set(lst_to_add)
    df_table['TEST'] = df_table['TEST'].isin(lst_to_add)
    

    如果内存有问题,您应该坚持使用布尔类型,并且只需要 01

    【讨论】:

    • 这太棒了!谢谢你的提示。这是现在将 set() 添加到上述解决方案的结果:[len lst : 4164 len df :10000 AddResultToTDB : 0.000 ms]
    • 这里有一些关于集合和列表之间区别的文档。我只是使用 set() 删除所有重复项,但我知道 set() 方法中的搜索使用哈希函数,解释了性能上的这种差异stackoverflow.com/questions/12354515/…
    • @BorisM 是的,set 对象通常用于从某些可迭代对象中获取一组唯一值,但这不是它们的主要用例。
    【解决方案2】:

    你可以的

    df_table['TEST'] = (df_table['id_row'].isin(lst_to_add)).astype(int)
    

    此代码检查 id_row 变量是否在 lst_to_add 中并返回 True 和 False,astype(int) 将其转换为 1 和 0。由于这种方法是矢量化的(作用于整个系列),它应该比使用apply 更快。

    【讨论】:

    • 感谢您的回答。我在一个小集合(10 000 行)上比较了结果,差异已经很大:[lambda:len lst:4164 len df:10000 AddResultToTDB:513.489 ms] [isin:len lst:4164 len df:10000 AddResultToTDB: 5.296 毫秒] 。明天我将与我的真实数据集进行比较。
    猜你喜欢
    • 2012-10-19
    • 2014-01-04
    • 2013-03-19
    • 2021-03-03
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    相关资源
    最近更新 更多