特定の列にマップする必要がある関数のディクショナリと集約したいグループ化されたDataFrameがあります。単一レベルの列の場合、これはgroups.agg({'colname': <function>})
。で簡単です。ただし、これをマルチレベルの列で機能させるのに苦労しています。この列からは、単一のレベルのみを参照したいと思います。
これが例です。
いくつかのサンプルデータを作成しましょう。
import itertools
import pandas as pd
lev1 = ['foo', 'bar', 'baz']
lev2 = list('abc')
n = 6
df = pd.DataFrame({k: np.random.randn(n) for k in itertools.product(lev1,lev2)},
index=pd.DatetimeIndex(start='2015-01-01', periods=n, freq='11D'))
それは次のようになります:
bar baz foo
a b c a b c a b c
2015-01-01 -1.11 2.12 -1.00 0.18 0.14 1.24 0.73 0.06 3.66
2015-01-12 -1.43 0.75 0.38 0.04 -0.33 -0.42 1.00 -1.63 -1.35
2015-01-23 0.01 -1.70 -1.39 0.59 -1.10 -1.17 -1.51 -0.54 -1.11
2015-02-03 0.93 0.70 -0.12 1.07 -0.97 -0.45 -0.19 0.11 -0.79
2015-02-14 0.30 0.49 0.60 -0.28 -0.38 1.11 0.15 0.78 -0.58
2015-02-25 -0.26 0.51 0.82 0.05 -1.45 0.14 0.53 -0.33 -1.35
そして、月ごとに次のようにグループ化します。
groups = df.groupby(pd.TimeGrouper('MS'))
列のトップレベルに基づいていくつかの関数を定義します。
funcs = {'bar': np.sum, 'baz': np.mean, 'foo': np.min}
ただし、groups.agg(funcs)
これを行うと、各レベルのキーが必要になるため、KeyErrorが発生します。これは理にかなっています。
これは、たとえば次のように機能します。
groups.agg({('bar', 'a'): np.mean})
bar
a
2015-01-01 -0.845554
2015-02-01 0.324897
しかし、私は2番目のレベルで各キーを指定したくありません。だから私は次のように機能するものを探しています:
groups.agg({('bar', slice(None)): np.mean})
しかし、aslice
はハッシュ化できないため、もちろん辞書に入れることはできません。
回避策は次のとおりです。
def multifunc(group):
func = funcs[group.name[0]]
return func(group)
groups.agg(multifunc)
しかし、それはあまり読みやすくなく、私には「パンドニック」に見えません。また、agg
関数と同じ列に複数の関数を配置することはできません。そのようなタスクを実行するためのより良い/標準的な方法がなければなりません、それは非常に珍しいことではありません。
これには近道はないと思います。幸いなことに、目的のdictを明示的に作成することはそれほど難しくありません。
result = groups.agg(
{(k1, k2): funcs[k1] for k1, k2 in itertools.product(lev1,lev2)})
import itertools
import numpy as np
import pandas as pd
lev1 = ['foo', 'bar', 'baz']
lev2 = list('abc')
n = 6
df = pd.DataFrame(
{k: np.random.randn(n) for k in itertools.product(lev1,lev2)},
index=pd.DatetimeIndex(start='2015-01-01', periods=n, freq='11D'))
groups = df.groupby(pd.TimeGrouper('MS'))
funcs = {'bar': np.sum, 'baz': np.mean, 'foo': np.min}
result = groups.agg(
{(k1, k2): funcs[k1] for k1, k2 in itertools.product(lev1,lev2)})
result = result.sortlevel(axis=1)
print(result)
収量
bar baz \
a b c a b c
2015-01-01 -2.144890 1.075044 1.038169 -0.460649 -0.309966 -0.211147
2015-02-01 1.313744 0.247171 1.049129 -0.174827 -0.437982 -0.196427
foo
a b c
2015-01-01 -1.358973 -1.846916 -0.896234
2015-02-01 -1.354953 -0.699607 0.288214
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加