【问题标题】:Faster way to count total occurrences of values in a column of lists in pandas?更快地计算熊猫列表列中值的总出现次数?
【发布时间】:2019-04-14 16:34:04
【问题描述】:

我在 pandas 数据框中有一列,其中包含大量标签列表:

>>> data['SPLIT'].head(10)
0    [33.23, 88.72, 38.93, E931.7, V09.0, 041.11, 5...
1    [99.04, 38.06, 39.57, 00.91, 55.69, V15.82, 27...
2    [96.04, 96.72, 401.9, 276.5, 584.9, 428.0, 507...
3    [96.6, 99.15, 99.83, V29.0, 765.15, 765.25, 77...
4    [96.71, 96.04, 54.12, 99.60, 38.93, 99.15, 53....
5    [88.72, 37.61, 39.61, 36.15, 36.12, 272.0, 401...
6    [38.93, 88.72, 37.31, 272.4, 719.46, 722.0, 31...
7    [88.72, 39.61, 35.71, 272.4, V12.59, 458.29, 7...
8    [97.44, 99.04, 88.56, 37.23, 39.95, 38.95, 00....
9    [00.14, 89.61, 39.95, E878.8, 244.9, 443.9, 18...

我要做的是遍历所有这些列表以查找每个值的总出现次数,以便我可以找到 50 个最常出现的值。

这是我使用的运行速度非常慢的代码:

test = pd.Series(sum([item for item in data.SPLIT], [])).value_counts()

我尝试在外面编写一个函数来循环遍历列表并找到计数,但这也很慢。

有什么方法可以修改这些数据或在 pandas 中使用与 df.groupby.count() 类似性能的函数?

我确实在 google 和 stackoverflow 上搜索了半小时,但没有一个答案具有更好的性能。我一直在尝试找出一种方法来展平列表或找到一种方法以更快的速度映射计数(迭代 500k 行,并且每个列表的长度各不相同,有些可能长达 512,其他短至 2)。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    使用带有展平的列表理解而不是sum

    test = pd.Series([x for item in data.SPLIT for x in item]).value_counts()
    

    或者通过chain.from_iterable进行展平:

    from itertools import chain
    
    test = pd.Series(list(chain.from_iterable(data.SPLIT))).value_counts()
    

    或者也使用collections.Counter:

    from itertools import chain
    from collections import Counter
    
    test = pd.Series(Counter(chain.from_iterable(data.SPLIT)))
    

    或者:

    import functools, operator
    
    test = pd.Series(functools.reduce(operator.iconcat, data.SPLIT, [])).value_counts()
    

    纯熊猫解决方案:

    test = pd.DataFrame(data.SPLIT.values.tolist()).stack().value_counts()
    

    【讨论】:

    • 天哪,第一个解决方案看起来和我写的几乎一样,但它几乎是瞬间完成的。太感谢了。我要弄清楚为什么你的速度这么快,感谢您的指导。
    • @BenCWang - 检查this - 还添加了最快的解决方案来回答。
    【解决方案2】:

    这个怎么样?

    import pandas as pd
    
    split = data["SPLIT"].apply(pd.Series)
    split = split.rename(columns = lambda x : 'val_' + str(x))
    split.melt(value_name="val").groupby(["val"]).size()
    

    【讨论】:

      猜你喜欢
      • 2018-07-17
      • 2018-05-05
      • 2023-01-17
      • 2019-02-14
      • 2018-04-04
      • 2019-02-22
      • 2019-06-18
      • 1970-01-01
      • 2020-10-09
      相关资源
      最近更新 更多