通常,如果日期是完全任意的,我认为您将不得不
for-loop在行上使用Python或[使用
df.apply,(实际上,它也使用Python循环。)
但是,如果您的日期(如上面的情况)共享一个公共频率,那么有一个比使用
df.apply以下方法要快得多的技巧:根据公共频率扩展时间序列-
在这种情况下为1分钟-填写NaN为零,然后调用
rolling_sum:
In [279]: pd.rolling_sum(df.set_index(['Date']).asfreq('1T').fillna(0), window=5, min_periods=1).reindex(df['Date'])Out[279]: ADate 2014-11-21 11:00:00 12014-11-21 11:03:00 52014-11-21 11:04:00 62014-11-21 11:05:00 72014-11-21 11:07:00 112014-11-21 11:08:00 82014-11-21 11:12:00 22014-11-21 11:13:00 3
当然,如果您愿意接受足够小的粒度,则任何时间序列都具有相同的频率,但是所需的大小
df.asfreq(...)可能会使此技巧不切实际。
这是使用的更通用方法的示例
df.apply。请注意,调用
searchsorted依赖
df['Date']于排序顺序。
import numpy as npimport pandas as pddf = pd.read_csv('data', parse_dates=[0], sep=',s*')start_dates = df['Date'] - pd.Timedelta(minutes=5)df['start_index'] = df['Date'].values.searchsorted(start_dates, side='right')df['end_index'] = np.arange(len(df))def sum_window(row): return df['A'].iloc[row['start_index']:row['end_index']+1].sum()df['rolling_sum'] = df.apply(sum_window, axis=1)print(df[['Date', 'A', 'rolling_sum']])
产量
Date A rolling_sum0 2014-11-21 11:00:00 1 11 2014-11-21 11:03:00 4 52 2014-11-21 11:04:00 1 63 2014-11-21 11:05:00 2 74 2014-11-21 11:07:00 4115 2014-11-21 11:08:00 1 86 2014-11-21 11:12:00 1 27 2014-11-21 11:13:00 2 3
这是一个比较
df.asfreq技巧和调用的基准
df.apply:
import numpy as npimport pandas as pddf = pd.read_csv('data', parse_dates=[0], sep=',s*')def big_df(df): df = df.copy() for i in range(7): dates = df['Date'] + pd.Timedelta(df.iloc[-1]['Date']-df.iloc[0]['Date']) + pd.Timedelta('1 minute') df2 = pd.Dataframe({'Date': dates, 'A': df['A']}) df = pd.concat([df, df2]) df = df.reset_index(drop=True) return dfdef using_apply(): start_dates = df['Date'] - pd.Timedelta(minutes=5) df['start_index'] = df['Date'].values.searchsorted(start_dates, side='right') df['end_index'] = np.arange(len(df)) def sum_window(row): return df['A'].iloc[row['start_index']:row['end_index']+1].sum() df['rolling_sum'] = df.apply(sum_window, axis=1) return df[['Date', 'rolling_sum']]def using_asfreq(): result = (pd.rolling_sum( df.set_index(['Date']).asfreq('1T').fillna(0), window=5, min_periods=1).reindex(df['Date'])) return result
In [364]: df = big_df(df)In [367]: %timeit using_asfreq()1000 loops, best of 3: 1.21 ms per loopIn [368]: %timeit using_apply()1 loops, best of 3: 208 ms per loop
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)