假设我有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;趋势(一个或多个)。
答案 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')