熊猫:通过多列进行转置和求和

时间:2019-08-02 09:31:46

标签: python-3.x pandas group-by transpose

我有这个数据框:

Html.LabelFor

它显示了用户访问不同类别和主题的时间。

我需要计算访问某个类别的用户还访问了某个主题的次数。因此输出应如下所示:

test = pd.DataFrame({
    'user': [1,2,3,4,5,6,7,8,9],
    'category1': [2,4,0,9,1,4,6,0,1],
    'category2': [1,0,1,3,2,0,0,9,0],
    'topic1': [3,2,1,4,2,0,0,1,2],
    'topic2': [0,0,7,2,1,4,6,0,0],

})

    user    category1   category2   topic1  topic2
0   1       2           1           3       0
1   2       4           0           2       0
2   3       0           1           1       7
3   4       9           3           4       2
4   5       1           2           2       1
5   6       4           0           0       4
6   7       6           0           0       6
7   8       0           9           1       0
8   9       1           0           2       0

将感谢您的帮助!

UPD:

我最终想出了这个解决方案,但我仍然认为应该有一种更优雅的方法...

    category    category_count  topic   topic_count
0   category1       27          topic1  13
1   category1       27          topic2  13
2   category2       16          topic1  11
3   category2       16          topic2  10

1 个答案:

答案 0 :(得分:3)

MultiIndex.from_product使用MultiIndex

mux = pd.MultiIndex.from_product([['category1','category2'],
                                  ['topic1','topic2']])
print (mux)
MultiIndex(levels=[['category1', 'category2'], 
                   ['topic1', 'topic2']],
           codes=[[0, 0, 1, 1], [0, 1, 0, 1]])

然后退出user列-通过下降或结束位置索引:

df = test.set_index('user')
#print (df)

在第一级和第二级使用DataFrame.reindex

df1 = df.reindex(mux, axis=1, level=0)
print (df1)
     category1        category2       
        topic1 topic2    topic1 topic2
user                                  
1            2      2         1      1
2            4      4         0      0
3            0      0         1      1
4            9      9         3      3
5            1      1         2      2
6            4      4         0      0
7            6      6         0      0
8            0      0         9      9
9            1      1         0      0

df2 = df.reindex(mux, axis=1, level=1)
print (df2)
     category1        category2       
        topic1 topic2    topic1 topic2
user                                  
1            3      0         3      0
2            2      0         2      0
3            1      7         1      7
4            4      2         4      2
5            2      1         2      1
6            0      4         0      4
7            0      6         0      6
8            1      0         1      0
9            2      0         2      0

因此categories的可能总和值,并通过DataFrame.whereDataFrame.gtsum进行主题过滤:

s1 = df1.sum().rename('category_count')
s2 = df2.where(df1.gt(0)).sum().astype(int).rename('topic_count')

最后加入在一起:

df = (pd.concat([s1, s2], axis=1)
        .rename_axis(('category','topic'))
        .reset_index()
        .sort_index(axis=1))
print (df)
    category  category_count   topic  topic_count
0  category1              27  topic1           13
1  category1              27  topic2           13
2  category2              16  topic1           11
3  category2              16  topic2           10