我正在尝试使用seaborn生成一个小提琴图。数据框 我使用的是在一列中包含几个分类值(用于x轴),每个分类值都有一个值数组(用于为每个分类值创建小提琴图)。一个小的工作示例是这样:
foo = pd.DataFrame(columns =['Names','Values'])
for i in range(10):
foo.loc[i] = ['no'+str(i),np.random.normal(i,2,10)]
但是尝试时
sns.violinplot(x='Names', y='Values', data=foo)
我收到以下错误
ValueError:
x
和y
变量都没有显示为数字。
现在,我可能会很hacky,只需将数组分成几行:
foo = pd.DataFrame(columns =['Names','Values'])
for i in range(3):
bar = np.random.normal(i,2,10)
for j,b in enumerate(bar):
foo.loc[i*10+j] = ['no'+str(i),b]
产生我想要的情节:
但是我猜想有一个更简单的解决方案,而无需重组我的数据框。
答案 0 :(得分:1)
pd.DataFrame.explode()
帮助您将列表列变成单独的单元格。将其转换为实际数字而不是字符串后,sns.violinplot
可以轻松绘制。
foo = foo.explode('Values')
foo['Values'] = foo['Values'].astype('float')
sns.violinplot(data=foo, x='Names', y='Values')
答案 1 :(得分:1)
在pandas 0.25中,您可以使用explode,对于以前的版本,请使用任何解决方案here:
result = foo.explode('Values').reset_index(drop=True)
result = result.assign(Names=result['Names'].astype('category'),
Values=result['Values'].astype(np.float32))
sns_plot = sns.violinplot(x='Names', y='Values', data=result)
爆炸(或取消嵌套)会将您的数据转换为:
Names Values
0 no0 3.352148
1 no0 2.195788
2 no0 1.234673
3 no0 0.084360
4 no0 1.778226
.. ... ...
95 no9 12.385434
96 no9 9.849669
97 no9 11.360196
98 no9 8.535900
99 no9 9.369197
[100 rows x 2 columns]
assign将dtypes转换为:
Names category
Values float32
dtype: object