web-dev-qa-db-ja.com

groupbyをプロットするときにSeabornで「入力を解釈できませんでした」エラー

このデータフレームがあるとしましょう

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'
10
marshallbanana

例外が発生する理由は、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を使用して同じ結果を得ることができます。

それが役に立てば幸い。

15
lrnzcig