import pandas as pd
#function to calculate
def masscenter(x):
print(x); # for debug purposes
return 0;
#simple DF creation routine
df = pd.DataFrame( [['02:59:47.000282', 87.60, 739],
['03:00:01.042391', 87.51, 10],
['03:00:01.630182', 87.51, 10],
['03:00:01.635150', 88.00, 792],
['03:00:01.914104', 88.00, 10]],
columns=['stamp', 'price','nQty'])
df['stamp'] = pd.to_datetime(df2['stamp'], format='%H:%M:%S.%f')
df.set_index('stamp', inplace=True, drop=True)
'stamp'是单调且唯一的,'price'是双精度且不包含NaN,'nQty'是整数且也不包含NaN。
所以,我需要计算滚动的'质心',即
sum(price*nQty)/sum(nQty)
。我目前尝试过的方法是:
df.apply(masscenter, axis = 1)
masscenter
会被调用5次,每次只有一行输入,输出结果如下:
price 87.6
nQty 739.0
Name: 1900-01-01 02:59:47.000282, dtype: float64
这是输入到masscenter
的期望,因为我可以通过x[0],x[1]
轻松访问price
和nQty
。然而,我在rolling.apply()
上遇到了困难。
阅读文档
DataFrame.rolling()和rolling.apply()
我认为在rolling()
中使用'axis'
,在apply
中使用'raw'
可以实现类似的行为。一个天真的方法
rol = df.rolling(window=2)
rol.apply(masscenter)
逐行打印(逐渐增加行数,直到窗口大小)
stamp
1900-01-01 02:59:47.000282 87.60
1900-01-01 03:00:01.042391 87.51
dtype: float64
那么
stamp
1900-01-01 02:59:47.000282 739.0
1900-01-01 03:00:01.042391 10.0
dtype: float64
所以,列被分别传递给
masscenter
(预期)。可悲的是,在文档中几乎没有关于
'axis'
的信息。然而,下一个变量显然是。rol = df.rolling(window=2, axis = 1)
rol.apply(masscenter)
从未调用
masscenter
并引发rol.apply(..)
中的ValueError
。> Length of passed values is 1, index implies 5
我承认我对'axis'参数以及它的工作原理不太确定,因为缺乏文档。这是问题的第一部分: 这里发生了什么?如何正确使用'axis'?它的设计目的是什么? 当然,之前有过答案,具体如下: 如何将函数应用于pandas数据框的两列 它适用于整个DataFrame,而不是滚动操作。
如何使用多列参数调用pandas滚动应用函数
答案建议编写自己的滚动函数,但对我来说,与评论中提到的问题是一样的:如果需要使用偏移窗口大小(例如'1T'
)来处理非均匀时间戳,该怎么办?
我不喜欢从头开始重新发明轮子的想法。而且我想要使用pandas来完成所有操作,以避免pandas和“自制滚动函数”之间的不一致性。
对于这个问题,还有另一个答案,建议分别填充数据框并计算所需内容,但这种方法行不通:存储数据的大小将会非常庞大。
这里提出了相同的想法:
在pandas数据框上应用滚动函数,使用多个参数
Pandas-using-rolling-on-multiple-columns
这个答案很好,离我的问题最近,但是再次强调,没有办法使用偏移窗口大小(
window = '1T'
)。一些答案是在pandas 1.0发布之前提出的,鉴于文档可能会更好,我希望现在可以同时在多个列上进行滚动。
问题的第二部分是: 在pandas 1.0.x中,有没有可能使用偏移窗口大小同时在多个列上进行滚动?
columns=['stamp', 'price','nQty']
? - Suthiro