使用Pandas绘制包含列表的列

时间:2016-10-26 08:03:01

标签: python list pandas plot dataframe

我有一个包含多个列的数据框(df),其中两个在每行中存储一个列表:

Index    list1                             list2
A   [ 0.09173306  0.12331911  0.20057651 ]  [ 0.3128322   0.27153913 ]
D   [ 0.03861522  0.10524985 ]              [ 0.37265687  0.48347806 ]
E   [ 0.02124905  0.01149118 ]              [ 0.04348405  0.17057435  0.37838683  0.37481453 ]

我想使用pandas内置plot函数将这些列表绘制为条形图。

使用

df.list1.apply(lambda x:x[0]).plot(kind='bar', width=0.9, ax=bar_ax)

我可以绘制每个列表的第一个元素。但是,尝试

df.list1.plot(kind='bar', width=0.9, ax=bar_ax)

导致以下错误:

Empty 'DataFrame': no numeric data to plot

我想做的是,(1)将两个列表都绘制成一个单独的情节,如下所示:

df[['list1','list2']].plot(kind='bar', width=0.9, ax=bar_ax)

(2)还将每个列表的第一个元素绘制成一个单独的条形图,我可以这样做:

df.list1.apply(lambda x:x[0]).plot(kind='bar', width=0.9, ax=bar_ax, color='blue')
df.list2.apply(lambda x:x[0]).plot(kind='bar', width=0.9, ax=bar_ax, color='red')

然而,这会导致条形图彼此重叠(未堆叠!) - 我希望将它们分组。

2 个答案:

答案 0 :(得分:3)

将此DF包含的值视为显示的列表:

np.random.seed(42)
df = pd.DataFrame({'list1': np.random.randint(0, 10, (5,2)).tolist(), 
                   'list2': np.random.randint(0, 10, (5,3)).tolist()}, 
                   index=list('ABCDE'))

Image

Q-1 将两个列表绘制成一个单独的图:

DF取消堆叠以使列名显示为索引,并使列表中的各个值出现在各个系列对象中。

df_lists = df[['list1','list2']].unstack().apply(pd.Series)
df_lists.plot.bar(rot=0, cmap=plt.cm.jet, fontsize=8, width=0.7, figsize=(8,4))

Image

Q-2 将每个列表的第一个元素绘制到一个单独的分组条形图中:

使用DF.applymap选择所需列的第一个元素以获取分组条形图。

df[['list1','list2']].applymap(lambda x: x[0]).plot.bar(rot=0, color=list('br'))

Image

答案 1 :(得分:1)

样品:

df = pd.DataFrame({'list1':[[ 0.09173306,  0.12331911,  0.20057651], [ 0.03861522,  0.10524985],[ 0.02124905,  0.01149118 ]],
                   'list2':[[0.3128322,   0.27153913], [0.37265687,  0.48347806], [0.04348405,  0.17057435,  0.37838683,  0.37481453]]},
                   index=['A','D','E'])
print (df)
                                  list1  \
A  [0.09173306, 0.12331911, 0.20057651]   
D              [0.03861522, 0.10524985]   
E              [0.02124905, 0.01149118]   

                                              list2  
A                           [0.3128322, 0.27153913]  
D                          [0.37265687, 0.48347806]  
E  [0.04348405, 0.17057435, 0.37838683, 0.37481453]  

第一个解决方案

import matplotlib.pyplot as plt

df.list1.apply(lambda x: pd.Series(x)).plot(kind='bar', width=0.9)
plt.show()

第二个带堆栈的解决方案

我认为您需要首先通过list构造函数SeriesDataFrame转换为dfL1 = pd.DataFrame(df.list1.values.tolist(), index=df.index).stack() print (dfL1) A 0 0.091733 1 0.123319 2 0.200577 D 0 0.038615 1 0.105250 E 0 0.021249 1 0.011491 dfL2 = pd.DataFrame(df.list2.values.tolist(), index=df.index).stack() print (dfL2) A 0 0.312832 1 0.271539 D 0 0.372657 1 0.483478 E 0 0.043484 1 0.170574 2 0.378387 3 0.374815 dtype: float64 来重新整形数据

df = pd.concat([dfL1, dfL2], axis=1, keys=('list1','list2'))
print (df)
        list1     list2
A 0  0.091733  0.312832
  1  0.123319  0.271539
  2  0.200577       NaN
D 0  0.038615  0.372657
  1  0.105250  0.483478
E 0  0.021249  0.043484
  1  0.011491  0.170574
  2       NaN  0.378387
  3       NaN  0.374815

然后stack他们在一起:

import matplotlib.pyplot as plt

df[['list1','list2']].plot(kind='bar', width=0.9)
plt.show()

最后concat

Keywords