我需要根据以下标准对 pandas Dataframe 进行分组,它类似于 ohlc 聚合:
open = last where volume > 0, in case there is no entry with volume > 0 use overall last
high = max
low = min
last = last
volume = max
我目前对这些操作(ohlc 聚合)的实现是:
ohlc_dict = {
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum',
}
df = df.groupby(pd.Grouper(freq='1Min',level=0,label='left')).agg(ohlc_dict)
我该如何解决这个问题?谢谢。
示例:
fi ts open high low close volume
datetime
2017-11-17 12:35:00 0 0 0.96214 0.96214 0.96214 0.96214 0
2017-11-17 12:35:00 0 0 0.96214 0.96214 0.96214 0.96214 0
2017-11-17 12:35:00 0 0 0.96214 0.96220 0.96214 0.96220 0
2017-11-17 12:35:00 0 0 0.96214 0.96220 0.96214 0.96220 0
2017-11-17 12:35:00 0 0 0.96214 0.96220 0.96214 0.96220 0
2017-11-17 12:35:00 0 0 0.96213 0.96220 0.96213 0.96219 19
2017-11-17 12:35:00 0 0 0.96214 0.96220 0.96214 0.96219 0
2017-11-17 12:35:00 0 0 0.96214 0.96222 0.96214 0.96222 0
2017-11-17 12:35:00 0 0 0.96214 0.96222 0.96214 0.96220 0
2017-11-17 12:35:00 0 0 0.96214 0.96222 0.96214 0.96221 0
2017-11-17 12:35:00 0 0 0.96214 0.96223 0.96214 0.96223 0
2017-11-17 12:35:00 0 0 0.96214 0.96223 0.96214 0.96221 0
2017-11-17 12:35:00 0 0 0.96214 0.96223 0.96214 0.96220 0
2017-11-17 12:35:00 0 0 0.96214 0.96223 0.96214 0.96220 0
2017-11-17 12:35:00 0 0 0.96213 0.96223 0.96213 0.96220 29
2017-11-17 12:35:00 0 0 0.96213 0.96223 0.96213 0.96220 29
2017-11-17 12:35:00 0 0 0.96214 0.96223 0.96214 0.96221 0
2017-11-17 12:35:00 0 0 0.96214 0.96223 0.96214 0.96222 0
期望的输出:
fi ts open high low close volume
datetime
2017-11-17 12:35:00 0 0 0.96213 0.96223 0.96213 0.96222 29
附加信息:
有两个数据源可以通过它们的“Volume”值来识别:
a. Volume = 0 (more frequent, less reliable)
b. Volume > 0 (less frequent, more reliable)
作为类型“b”。更可靠,最好使用它的开放值来键入'a'开放值。
至于 last 聚合是否真的很重要,老实说,其他聚合(first,max,min)会起作用,因为开放值是一分钟内的第一个引用值(在这个例子中)并且永远不会变化。
当与服务器的连接中断时,会出现不正确值的问题。 “a”类型的数据无法处理这个问题,可能会给我错误的值,“b”类型的数据可以很好地处理这个问题,并会给我正确的值。
最佳答案
您可以先按 open
列的 last
进行聚合:
ohlc_dict = {
'high': 'max',
'low': 'min',
'close': 'last',
'open':'last',
'volume':'sum'
}
g = df.groupby(pd.Grouper(freq='1Min',level=0,label='left'))
df2 = g.agg(ohlc_dict)
print (df2)
low close high open volume
datetime
2017-11-17 12:35:00 0.96213 0.96222 0.96223 0.96215 77
然后过滤掉所有 0
卷并仅聚合 open
的最后一个值:
g1 = df[df['volume'] > 0].groupby(pd.Grouper(freq='1Min',level=0,label='left'))
df1 = g1['open'].last().reindex(df2.index)
print (df1)
datetime
2017-11-17 12:35:00 0.96213
Freq: T, Name: open, dtype: float64
最后使用 to_frame
将两个 DataFrame 合并为一个和 combine_first
:
df3 = df1.to_frame().combine_first(df2)
print (df3)
close high low open volume
datetime
2017-11-17 12:35:00 0.96222 0.96223 0.96213 0.96213 77.0
在条件下使用自定义函数(较慢):
def ohlc_func(x):
a = x.loc[x['volume'] > 0, 'open'].tail(1)
a = a.item() if len(a) == 1 else x['open'].tail(1)[0]
b = x['high'].max()
c = x['low'].min()
d = x['close'].tail(1)[0]
e = x['volume'].sum()
col = ['open','high','low','close','volume']
return pd.Series([a,b,c,d,e], index=col)
df = df.groupby(pd.Grouper(freq='1Min',level=0,label='left')).apply(ohlc_func)
print (df)
open high low close volume
datetime
2017-11-17 12:35:00 0.96213 0.96223 0.96213 0.96222 77.0
关于python - 使用来自不同列的条件语句进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47350677/