Pandas groupby和值计数具有多次出现的复杂字符串

时间:2018-04-30 09:19:23

标签: python pandas

假设我有df这样:

    stringOfInterest        trend                  
0         C                    up
1         D                  down
2         E                  down
3         C,O                  up
4         C,P                  up

我想使用df将此pandas绘制为条形图。为了获得正确的分组条形图,我想按照df["trend"]列对数据进行分组,然后计算<{>>每个字母的df["stringOfInterest"]的出现次数。 可以看出,这些字符串中的一些包含由&#34;,#34;分隔的多个字母。

使用

df.groupby("trend").stringOfInterest.value_counts().unstack(0)

产生预期结果:

trend                  down    up
stringOfInterest                        
-                       7.0   8.0
C                       3.0  11.0
C,O                     NaN   2.0
C,P                     1.0   1.0
D                       1.0   2.0
E                      15.0  14.0
E,T                     1.0   NaN

但是,我想计算单个字符(C,E,D,...)的出现次数。 在原df上,这可以像这样实现:

s = df.stringOfInterest.str.split(",", expand = True).stack()
s.value_counts()

这通常会生成以下内容:

C     3
E     2
D     1
O     1
P     1
T     1

不幸的是,groupby()unstack()结合使用后,此处无法使用。

也许我走错了路,一些更优雅的方式会更受欢迎。

澄清绘图:对于每个字母(stringOfInterest),必须有两个条形表示&#34; up&#34; &#34; down&#34;趋势(一个或多个)。

1 个答案:

答案 0 :(得分:2)

基于此答案:Pandas expand rows from list data available in column

这会对你有所帮助吗?

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    {'stringOfInterest': {0: 'C', 1: 'D', 2: 'E', 3: 'C,O', 4: 'C,P'},
     'trend': {0: 'up', 1: 'down', 2: 'down', 3: 'up', 4: 'up'}})


df2 = (pd.DataFrame(df.stringOfInterest.str.split(',').tolist(), index=df.trend)
        .stack()
        .reset_index()
        .groupby('trend')[0]
        .value_counts()
        .unstack()
      ).T

df2.plot(kind='bar')
plt.show()

另一种方法

我们也可以将列压缩并展开。

import pandas as pd
from collections import Counter

data = [(x,i) for x,y in zip(df.trend,df.stringOfInterest.str.split(',')) for i in y]

pd.Series(Counter(data)).plot(kind='bar')