resampling
は、TimeGrouper
でグループ化するのと同じです。 resampling
の how
パラメータのみ、列ごとに集計を指定することを可能にしながら、df.groupby(...)
によって返さ GroupBy
目的は、様々な方法でグループを集約するために、様々な機能(例えばmean
、sum
、又はcount
)を渡すことができるagg
方法を有しています。あなたは希望のデータフレームを構築するために、これらの結果を使用することができます。
import datetime as DT
import numpy as np
import pandas as pd
np.random.seed(2016)
date_times = pd.date_range(DT.datetime(2012, 4, 5, 8, 0),
DT.datetime(2012, 4, 5, 12, 0),
freq='1min')
tamb = np.random.sample(date_times.size) * 10.0
radiation = np.random.sample(date_times.size) * 10.0
df = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation},
index=date_times)
resampled = df.resample('1H', how={'radiation': np.sum, 'tamb': np.mean})
print(resampled[['radiation', 'tamb']])
# radiation tamb
# 2012-04-05 08:00:00 279.432788 4.549235
# 2012-04-05 09:00:00 310.032188 4.414302
# 2012-04-05 10:00:00 257.504226 5.056613
# 2012-04-05 11:00:00 299.594032 4.652067
# 2012-04-05 12:00:00 8.109946 7.795668
def using_agg(df):
grouped = df.groupby(pd.TimeGrouper('1H'))
return pd.DataFrame(
{'radiation': grouped['radiation'].agg('sum'),
'tamb': grouped['tamb'].agg('mean'),
'new_column': grouped['tamb'].agg('count')})
print(using_agg(df))
利回り
new_column radiation tamb
2012-04-05 08:00:00 60 279.432788 4.549235
2012-04-05 09:00:00 60 310.032188 4.414302
2012-04-05 10:00:00 60 257.504226 5.056613
2012-04-05 11:00:00 60 299.594032 4.652067
2012-04-05 12:00:00 1 8.109946 7.795668
は私の最初の答えはgroupby/apply
を使うことを提案注意:
def using_apply(df):
grouped = df.groupby(pd.TimeGrouper('1H'))
result = grouped.apply(foo).unstack(-1)
result = result.sortlevel(axis=1)
return result[['radiation', 'tamb', 'new_column']]
def foo(grp):
radiation = grp['radiation'].sum()
tamb = grp['tamb'].mean()
cnt = grp['tamb'].count()
return pd.Series([radiation, tamb, cnt], index=['radiation', 'tamb', 'new_column'])
それはapply
を使用していることが判明しますここagg
を使用するよりもはるかに遅いです。1681行のデータフレーム上のusing_apply
対我々のベンチマークusing_agg
場合:
np.random.seed(2016)
date_times = pd.date_range(DT.datetime(2012, 4, 5, 8, 0),
DT.datetime(2012, 4, 6, 12, 0),
freq='1min')
tamb = np.random.sample(date_times.size) * 10.0
radiation = np.random.sample(date_times.size) * 10.0
df = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation},
index=date_times)
私は
In [83]: %timeit using_apply(df)
100 loops, best of 3: 16.9 ms per loop
In [84]: %timeit using_agg(df)
1000 loops, best of 3: 1.62 ms per loop
using_agg
が大幅に高速using_apply
と(追加 %timeit
試験に基づく)の速度よりもIPythonの%timeit
機能を使用して見つけます有利な点はusing_agg
のように成長し、 が生育する。 how
dictのは、非existant列名を受け入れないという問題以外にも
frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean,\
'new_column': count()})
に関するところで
、count
中括弧は問題があります。 how
dictの値は関数オブジェクトでなければなりません。 count
は関数オブジェクトですが、count()
はcount
を呼び出して返される値です。
Pythonは呼び出す関数の前に引数を評価しているので、count()
はframe.resample(...)
前に呼び出さなっている、とcount()
の戻り値は、その後how
パラメータにバインドされた辞書にキー'new_column'
と関連しています。それはあなたが望むものではありません。更新質問について
:事前計算あなたがgroupby/agg
を呼び出す前が必要になります値:
代わり
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1'][grouped['col1'] > 0].agg('sum')
...
# ImplementationError since `grouped['col1']` does not implement __getitem__
の使用 df['col1_pos'] = df['col1'].clip(lower=0)
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1_pos'].agg('sum')
...
bottom of this post用を参照してください。より多くのなぜ事前計算がパフォーマンスに役立つのか?
詳細でわかりやすい説明をありがとうございます。私は本当にそれを感謝します。答えは私にたくさん教えられています。ありがとうございました。 – codingknob
質問:foo(grp)のアグリゲータの連続計算と比較して、カラム演算ごとにアグリゲータを実行する方法に違いがあります。私の場合は、foo(grp)に30個のアグリゲータがあります。これは、同じアグリゲータを一度に繰り返しているため、時間がかかります。 how =が同じように機能するかどうかは不明です。スピードの計算をベクトル化する方法があるのだろうか? – codingknob
実際、 'apply 'を使う私の最初の提案は良いものではなかったと思います。もっと速い方法があります: 'groupby/apply'の代わりに' groupby/agg'を使います。私は自分の投稿を編集して、私が意味することを示しています。 – unutbu