[英]pandas dataframe resample aggregate function use multiple columns with a customized function?
這是一個例子:
# Generate some random time series dataframe with 'price' and 'volume'
x = pd.date_range('2017-01-01', periods=100, freq='1min')
df_x = pd.DataFrame({'price': np.random.randint(50, 100, size=x.shape), 'vol': np.random.randint(1000, 2000, size=x.shape)}, index=x)
df_x.head(10)
price vol
2017-01-01 00:00:00 56 1544
2017-01-01 00:01:00 70 1680
2017-01-01 00:02:00 92 1853
2017-01-01 00:03:00 94 1039
2017-01-01 00:04:00 81 1180
2017-01-01 00:05:00 70 1443
2017-01-01 00:06:00 56 1621
2017-01-01 00:07:00 68 1093
2017-01-01 00:08:00 59 1684
2017-01-01 00:09:00 86 1591
# Here is some example aggregate function:
df_x.resample('5Min').agg({'price': 'mean', 'vol': 'sum'}).head()
price vol
2017-01-01 00:00:00 78.6 7296
2017-01-01 00:05:00 67.8 7432
2017-01-01 00:10:00 76.0 9017
2017-01-01 00:15:00 74.0 6989
2017-01-01 00:20:00 64.4 8078
但是,如果我想提取其他聚合信息取決於多個列,我該怎么辦?
例如,我想在這里追加2個列,稱為all_up
和all_down
。
這兩列的計算定義如下:
在每5分鍾,1分鍾采樣價格下降多少次,vol下降,調用此列all_down
,以及它們上升了多少次,將此列all_up
。
這是我期望2列的樣子:
price vol all_up all_down
2017-01-01 00:00:00 78.6 7296 2 0
2017-01-01 00:05:00 67.8 7432 0 0
2017-01-01 00:10:00 76.0 9017 1 0
2017-01-01 00:15:00 74.0 6989 1 1
2017-01-01 00:20:00 64.4 8078 0 2
此功能取決於2列。 但是在Resampler
對象的agg
函數中,它似乎只接受3種函數:
str
或函數分別應用於每個列。 list
。 dict
與列名匹配。 仍然只是每次都將函數值應用於單個列。 所有這些功能似乎都不符合我的需求。
我認為您需要resample
使用groupby
+ Grouper
並apply
自定義函數:
def func(x):
#code
a = x['price'].mean()
#custom function working with 2 columns
b = (x['price'] / x['vol']).mean()
return pd.Series([a,b], index=['col1','col2'])
df_x.groupby(pd.Grouper(freq='5Min')).apply(func)
或者對所有支持的aggreagate函數使用resample
,並將輸出與自定義函數的輸出一起連接:
def func(x):
#custom function
b = (x['price'] / x['vol']).mean()
return b
df1 = df_x.groupby(pd.Grouper(freq='5Min')).apply(func)
df2 = df_x.resample('5Min').agg({'price': 'mean', 'vol': 'sum'}).head()
df = pd.concat([df1, df2], axis=1)
編輯:對於檢查遞減和增加使用函數diff
並與0
比較,將兩個條件與&
並且按sum
計數:
def func(x):
v = x['vol'].diff().fillna(0)
p = x['price'].diff().fillna(0)
m1 = (v > 0) & (p > 0)
m2 = (v < 0) & (p < 0)
return pd.Series([m1.sum(), m2.sum()], index=['all_up','all_down'])
df1 = df_x.groupby(pd.Grouper(freq='5min')).apply(func)
print (df1)
all_up all_down
2017-01-01 00:00:00 2 0
2017-01-01 00:05:00 0 0
df2 = df_x.resample('5Min').agg({'price': 'mean', 'vol': 'sum'}).head()
df = pd.concat([df2, df1], axis=1)
print (df)
vol price all_up all_down
2017-01-01 00:00:00 7296 78.6 2 0
2017-01-01 00:05:00 7432 67.8 0 0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.