20

数値と部分的に重複するインデックスを持つ一連の DataFrames があります。インデックスが複数の DataFrame で発生する場合は、それらをマージして平均を取りたいと思います。

import pandas as pd
import numpy as np

df1 = pd.DataFrame([1,2,3], columns=['col'], index=['a','b','c'])
df2 = pd.DataFrame([4,5,6], columns=['col'], index=['b','c','d'])

これにより、2 つの DataFrame が得られます。

   col            col
a    1        b     4
b    2        c     5
c    3        d     6

ここで、DataFrames をマージして、各インデックスの平均を取得したいと思います (該当する場合、つまり複数回発生する場合)。

次のようになります。

    col
a     1
b     3
c     4
d     6

高度なマージ/結合でこれを行うことはできますか?

4

2 に答える 2

5
In [22]: pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1)
Out[23]: 
a    1
b    3
c    4
d    6
dtype: float64

ローマンの質問に関しては、IPython%timeitコマンドがコードをベンチマークする便利な方法だと思います。

In [28]: %timeit df3 = pd.concat((df1, df2)); df3.groupby(df3.index).mean()
1000 loops, best of 3: 617 µs per loop

In [29]: %timeit pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1)
1000 loops, best of 3: 577 µs per loop

In [39]: %timeit pd.concat((df1, df2), axis=1).mean(axis=1)
1000 loops, best of 3: 524 µs per loop

この場合、pd.concat(...).mean(...)少し高速であることがわかります。しかし実際には、より意味のあるベンチマークを得るために、より大きなデータフレームをテストする必要があります。

ちなみに、IPython をインストールしたくない場合は、Python のtimeitモジュールを使用して同等のベンチマークを実行できます。もう少しセットアップが必要です。ドキュメントには、これを行う方法を示すいくつかの例があります。


たとえば、次のように、インデックスに重複するエントリがある場合、df1またはあった場合に注意してください。df2

N = 1000
df1 = pd.DataFrame([1,2,3]*N, columns=['col'], index=['a','b','c']*N)
df2 = pd.DataFrame([4,5,6]*N, columns=['col'], index=['b','c','d']*N)

次に、これら 3 つの答えは異なる結果をもたらします。

In [56]: df3 = pd.concat((df1, df2)); df3.groupby(df3.index).mean()
Out[56]: 
   col
a    1
b    3
c    4
d    6

pd.mergeおそらく、あなたが望むような答えは得られません:

In [58]: len(pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1))
Out[58]: 2002000

pd.concat((df1, df2), axis=1)ValueErrorを発生させながら:

In [48]: pd.concat((df1, df2), axis=1)
ValueError: cannot reindex from a duplicate axis
于 2013-10-21T09:05:27.217 に答える