如何分组并计算数据框中的列表值

How can I group by and count list value in dataframe

我有数据框

df = pd.DataFrame({'session_id': ['T01', 'T02', 'T03', 'T04', 'T05', 'T06', 'T07'],
                   'path': [array(['a', 'b', 'c'], dtype='<U1'),
                            array(['x', 'y', 'z'], dtype='<U1'),
                            array(['a', 'b', 'c'], dtype='<U1'),
                            array(['x', 'y', 'z'], dtype='<U1'),
                            array(['k'], dtype='<U1'),
                            array(['x', 'y', 'z'], dtype='<U1'),
                            array(['h', 'i'], dtype='<U1')],
                   'flag': [0, 1, 0, 0, 0, 1, 0],
                   'total_value': [0.02, 0.05, 0.02, 0.05, 0.001, 0.05, 0.03]})

像下面这样table

| session_id |         path         | flag  |   total_value |
| ---------- | -------------------- | ----- | ------------- |
| T01        | [a,b,c]              | 0     | 0.020         |
| T02        | [x,y,z]              | 1     | 0.050         |
| T03        | [a,b,c]              | 0     | 0.020         |
| T04        | [x,y,z]              | 0     | 0.050         |
| T05        | [k]                  | 0     | 0.001         |
| T06        | [x,y,z]              | 1     | 0.050         |
| T07        | [h,i]                | 0     | 0.030         |

我想按路径、标志、total_value 分组,然后计算记录数,然后按 total_value desc 排序。最终结果选择如下。


|         path         | flag  |   total_value |  count  |
| -------------------- | ----- | ------------- | ------- |
| [x,y,z]              | 1     | 0.050         |  2      |
| [x,y,z]              | 0     | 0.050         |  1      |
| [h,i]                | 0     | 0.030         |  1      |
| [a,b,c]              | 0     | 0.020         |  2      |
| [k]                  | 0     | 0.001         |  1      |

我试着用

df.groupby(['path', 'flag', 'total_value']).count()

但会显示错误

unhashable type: 'numpy.ndarray'

groupby 的问题在于,正如错误消息所说,np.ndarrays 是可变的,因此不可散列,因此不能用作索引。但是元组是可散列的,因此您可以将 'path' 列中的数组转换为所需列上的元组和 groupby 并使用 count 方法。

然后在操作之后,将'path'值转换回np.arrays:

df['path'] = df['path'].apply(tuple)
out = df.groupby(['path', 'flag', 'total_value']).count().reset_index()
out['path'] = out['path'].apply(np.array)

输出:

        path  flag  total_value  session_id
0  [a, b, c]     0        0.020           2
1     [h, i]     0        0.030           1
2        [k]     0        0.001           1
3  [x, y, z]     0        0.050           1
4  [x, y, z]     1        0.050           2