2016-03-29 5 views
3

の=私は解決策resample a dataframe with different functions applied to each column?リサンプル

をして読んでいた方には、インサートの新しい非既存の列:

frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean}) 

言って、私は保存する結果に非既存の列を追加したい場合count()のような他の関数の値。与えられた例では、私は、各1H期間内の行数を計算したい場合は言います。

を行うことが可能です:

frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean,\ 
       'new_column': count()}) 

注、NEW_COLUMNは、元のデータフレーム内の既存の列ではありません。

私が尋ねる理由は、私がこれを行う必要があると私は非常に大規模なデータフレームを持っていると私はちょうどリサンプル期間にカウントを取得するために二回、元のDFをリサンプリングしたくないです。

私は今以上にしようとしている、それは非常に長い時間(構文エラー)を服用しているようです。 Pythonは永遠にループのいくつかの並べ替え中に閉じ込められているかどうかわかりません。

更新:

私が(そのために親切にありがとう)AGGを使用するための提案を実施しました。

grouped = df.groupby(['name1',pd.TimeGrouper('M')]) 
    return pd.DataFrame(
    {'new_col1': grouped['col1'][grouped['col1'] > 0].agg('sum') 
    ... 


/Users/blahblah/anaconda/lib/python2.7/site-packages/pandas/core/groupby.pyc in __getitem__(self, key) 
    521 
    522  def __getitem__(self, key): 
--> 523   raise NotImplementedError('Not implemented: %s' % key) 
    524 
    525  def _make_wrapper(self, name): 

NotImplementedError: Not implemented: True 

次の作品は、私がgrouped.apply(foo)を使用する:最初の集約を計算するとき

しかし、私は、次のエラーを受信しました。

new_col1 = grp['col1'][grp['col1'] > 0].sum() 

答えて

3

resamplingは、TimeGrouperでグループ化するのと同じです。 resamplinghowパラメータのみ、列ごとに集計を指定することを可能にしながら、df.groupby(...)によって返さ GroupBy目的は、様々な方法でグループを集約するために、様々な機能(例えばmeansum、又は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用を参照してください。より多くのなぜ事前計算がパフォーマンスに役立つのか?

+0

詳細でわかりやすい説明をありがとうございます。私は本当にそれを感謝します。答えは私にたくさん教えられています。ありがとうございました。 – codingknob

+0

質問:foo(grp)のアグリゲータの連続計算と比較して、カラム演算ごとにアグリゲータを実行する方法に違いがあります。私の場合は、foo(grp)に30個のアグリゲータがあります。これは、同じアグリゲータを一度に繰り返しているため、時間がかかります。 how =が同じように機能するかどうかは不明です。スピードの計算をベクトル化する方法があるのだろうか? – codingknob

+0

実際、 'apply 'を使う私の最初の提案は良いものではなかったと思います。もっと速い方法があります: 'groupby/apply'の代わりに' groupby/agg'を使います。私は自分の投稿を編集して、私が意味することを示しています。 – unutbu

関連する問題