Skip to main content
 首页 » 编程设计

Python:Pandas:获取不同列的所有组合及其频率

2025年05月04日14daizhj

我有一个包含三列的 python 数据框。

    a   b   c 
0   1   2   3 
1   1   2   3 
2   1   2   8 
3   1   5   9 
4   1   3   7 
5   1   3   4 

我想找到 a,b,c 的所有组合,我的预期结果是这样的:

[1,2,3]: 2  # from row 0 and row 1 
[1,2]  : 3  # from row 0 and row 1 and row 2 
[1,3]  : 4  # from row 0, 1, 4, 5 
[1,4]  : 1 
[1,5]  : 1 
[1,7]  : 1 
[1,8]  : 1 
[1,9]  : 1 
[2,3]  : 2 
............ 

随意使用任何包。

import pandas as pd 
pd.DataFrame(data=[[1,2,3],[1,2,3],[1,2,8],[1,5,9],[1,3,7],[1,3,4]],columns=['a','b','c']) 

请您参考如下方法:

恶心的一行字:

In [114]: collections.Counter(map(str, itertools.chain.from_iterable(list(df.apply(lambda x: list(itertools.chain.from_iterable([list(itertools.combinations(x, k)) for k in range(1, 4)])), axis=1).values)))) 
Out[114]:  
Counter({'(1, 2)': 3, 
         '(1, 2, 3)': 2, 
         '(1, 2, 8)': 1, 
         '(1, 3)': 4, 
         '(1, 3, 4)': 1, 
         '(1, 3, 7)': 1, 
         '(1, 4)': 1, 
         '(1, 5)': 1, 
         '(1, 5, 9)': 1, 
         '(1, 7)': 1, 
         '(1, 8)': 1, 
         '(1, 9)': 1, 
         '(1,)': 6, 
         '(2, 3)': 2, 
         '(2, 8)': 1, 
         '(2,)': 3, 
         '(3, 4)': 1, 
         '(3, 7)': 1, 
         '(3,)': 4, 
         '(4,)': 1, 
         '(5, 9)': 1, 
         '(5,)': 1, 
         '(7,)': 1, 
         '(8,)': 1, 
         '(9,)': 1}) 

一些解释:

  1. 由于 df.apply(..., axis=1,它首先在每一行上应用 lambda 函数。

  2. lambda 函数创建行值的所有可能组合,而不管条目的数量。

  3. 我们将所有找到的值按行合并到一个列表中。那是第一个 itertools.chain.from_iterable开始。

  4. 我们将所有行值合并到一个列表中,使用第二个 itertools.chain.from_iterable。

  5. 感谢collections.Counter,我们描述了结果, 并获取频率。

编辑

相同的解决方案,但不使用 itertools.chain.from_iterable

In [25]: collections.Counter([str(k) for l in df.apply(lambda x: [c for i in range(1, 4) for c in itertools.combinations(x, i)], axis=1).values for k in l]) 

这一次,我利用列表理解来实现相同的结果,这可能会导致一个更具可读性的解决方案。 步骤大致相同,没有“列表合并”的麻烦。