首页 > 解决方案 > Python Pandas - 如何按具有多个值的多列中的值按计数分组

问题描述

我的数据包括一些变量,其中包含来自多答案问题的数据。这些存储为字符串(逗号分隔)并且不按值排序。

我需要同时对 2 个或更多这些变量进行不同的计数,即获取它们唯一值的每个组合的频率。

我还有第二个数据框,其中包含每个变量的可用代码

df_meta['a']['Categories'] = ['1', '2', '3','4']
df_meta['b']['Categories'] = ['1', '2']

如果这是我的数据

df = pd.DataFrame(np.array([["1,3","1"],["3","1,2"],["1,3,2","1"],["3,1","2,1"]]),
                  columns=['a', 'b'])


index  a      b     
1      1,3    1
2      3      1,2
3      1,3,2  1
4      3,1    2,1

理想情况下,这就是输出的样子

a  b   count
1  1   3
1  2   1
2  1   1
2  2   0
3  1   4
3  2   2
4  1   0
4  2   0

虽然如果我不可能得到零计数,这会很好

a  b   count
1  1   3
1  2   1
2  1   1
3  1   4
3  2   2

到目前为止,我通过使用 split 和 value_counts 分别获得了每个变量的计数

df["a"].str.split(',',expand=True).stack().value_counts()
3    4
1    3
2    1

df["b"].str.split(',',expand=True).stack().value_counts()
1    4
2    2

但是由于索引的差异,我无法弄清楚如何按它们进行分组。

df2 = pd.DataFrame()
df2["a"] = df["a"].str.split(',',expand=True).stack()
df2["b"] = df["b"].str.split(',',expand=True).stack()
df2.groupby(['a','b']).size()

a  b
1  1    3
3  1    1
   2    1

有没有办法调整 groupby 只计算第一个索引的实例或另一种方法来更有效地计算唯一组合?

我也可以使用 df_meta 数据框遍历所有代码,但是一些实际变量有 300-400 个代码,而且速度非常慢,当我尝试跨越其中的 2-3 个代码时,如果可以使用 groupby 或其他函数,它应该工作得更快。

标签: pythonpandassplitpandas-groupby

解决方案


首先,我们让您的数据框开始。

df = pd.DataFrame(np.array([["1,3","1"],["3","1,2"],["1,3,2","1"], 
     ["3,1","2,1"]]),columns=['a', 'b'])

然后将列拆分为单独的数据框。

da = df["a"].str.split(',',expand=True)
db = df["b"].str.split(',',expand=True)

循环遍历所有行和两个数据框。制作所有组合的临时数据框并将它们添加到列表中。

ab = list()
for r in range(len(da)):
    for i in da.iloc[r,:]:
        for j in db.iloc[r,:]:
            if i != None and j != None:
                daf = pd.DataFrame({'a':[i], 'b':[j]})
                ab.append(daf)

将临时数据帧列表连接到一个新数据帧中。

 dfn = pd.concat(ab)

Groupby 与 'a' 和 'b' 列和 size() 给你答案。

 print(dfn.groupby(['a', 'b']).size().reset_index(name='count'))

   a  b  count
0  1  1      3
1  1  2      1
2  2  1      1
3  3  1      4
4  3  2      2

推荐阅读