このデータフレームがあるとしましょう
d = { 'Path' : ['abc', 'abc', 'ghi','ghi', 'jkl','jkl'],
'Detail' : ['foo', 'bar', 'bar','foo','foo','foo'],
'Program': ['prog1','prog1','prog1','prog2','prog3','prog3'],
'Value' : [30, 20, 10, 40, 40, 50],
'Field' : [50, 70, 10, 20, 30, 30] }
df = DataFrame(d)
df.set_index(['Path', 'Detail'], inplace=True)
df
Field Program Value
Path Detail
abc foo 50 prog1 30
bar 70 prog1 20
ghi bar 10 prog1 10
foo 20 prog2 40
jkl foo 30 prog3 40
foo 30 prog3 50
私はそれを問題なく集計できます(これを行うより良い方法がある場合は、ところで知りたいのですが!)
df_count = df.groupby('Program').count().sort(['Value'], ascending=False)[['Value']]
df_count
Program Value
prog1 3
prog3 2
prog2 1
df_mean = df.groupby('Program').mean().sort(['Value'], ascending=False)[['Value']]
df_mean
Program Value
prog3 45
prog2 40
prog1 20
Pandas問題なくプロットできます...
df_mean.plot(kind='bar')
しかし、シーボーンで試したときにこのエラーが発生するのはなぜですか?
sns.factorplot('Program',data=df_mean)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-26-23c2921627ec> in <module>()
----> 1 sns.factorplot('Program',data=df_mean)
C:\Anaconda3\lib\site-packages\seaborn\categorical.py in factorplot(x, y, hue, data, row, col, col_wrap, estimator, ci, n_boot, units, order, hue_order, row_order, col_order, kind, size, aspect, orient, color, palette, legend, legend_out, sharex, sharey, margin_titles, facet_kws, **kwargs)
2673 # facets to ensure representation of all data in the final plot
2674 p = _CategoricalPlotter()
-> 2675 p.establish_variables(x_, y_, hue, data, orient, order, hue_order)
2676 order = p.group_names
2677 hue_order = p.hue_names
C:\Anaconda3\lib\site-packages\seaborn\categorical.py in establish_variables(self, x, y, hue, data, orient, order, hue_order, units)
143 if isinstance(input, string_types):
144 err = "Could not interperet input '{}'".format(input)
--> 145 raise ValueError(err)
146
147 # Figure out the plotting orientation
ValueError: Could not interperet input 'Program'
例外が発生する理由は、df_mean
操作の後にProgram
がデータフレームdf_count
およびgroup_by
のインデックスになるためです。
df_mean
からfactorplot
を取得したい場合、簡単な解決策は、インデックスを列として追加することです。
In [7]:
df_mean['Program'] = df_mean.index
In [8]:
%matplotlib inline
import seaborn as sns
sns.factorplot(x='Program', y='Value', data=df_mean)
ただし、factorplot
に計算を任せるだけで、
sns.factorplot(x='Program', y='Value', data=df)
同じ結果が得られます。それが役に立てば幸い。
コメントの後に編集
確かに、パラメータas_index
について非常に良い指摘をしています。デフォルトではTrueに設定されており、その場合、質問のようにProgram
がインデックスの一部になります。
In [14]:
df_mean = df.groupby('Program', as_index=True).mean().sort(['Value'], ascending=False)[['Value']]
df_mean
Out[14]:
Value
Program
prog3 45
prog2 40
prog1 20
明確にするために、この方法ではProgram
はもはや列ではなく、インデックスになります。トリックdf_mean['Program'] = df_mean.index
は実際にインデックスをそのまま保持し、インデックスの新しい列を追加するため、Program
が複製されます。
In [15]:
df_mean['Program'] = df_mean.index
df_mean
Out[15]:
Value Program
Program
prog3 45 prog3
prog2 40 prog2
prog1 20 prog1
ただし、as_index
をFalseに設定すると、Program
が列として追加され、新しい自動インクリメントインデックスが追加されます。
In [16]:
df_mean = df.groupby('Program', as_index=False).mean().sort(['Value'], ascending=False)[['Program', 'Value']]
df_mean
Out[16]:
Program Value
2 prog3 45
1 prog2 40
0 prog1 20
これにより、seaborn
に直接フィードできます。それでも、df
を使用して同じ結果を得ることができます。
それが役に立てば幸い。