Sut*_*iro 12 python dataframe pandas rolling-computation
我正在尝试pandas.DataFrame.rolling.apply()
在多列上使用滚动函数。Python 版本是 3.7,pandas 是 1.0.2。
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)
Run Code Online (Sandbox Code Playgroud)
'stamp'
是单调且唯一的,'price'
是双精度'nQty'
值且不包含 NaN,是整数且也不包含 NaN。
所以,我需要计算滚动的“质心”,即sum(price*nQty)/sum(nQty)
。
到目前为止我尝试过的:
df.apply(masscenter, axis = 1)
Run Code Online (Sandbox Code Playgroud)
masscenter
被单行调用 5 次,输出将类似于
price 87.6
nQty 739.0
Name: 1900-01-01 02:59:47.000282, dtype: float64
Run Code Online (Sandbox Code Playgroud)
这是 a 的理想输入masscenter
,因为我可以轻松访问price
和nQty
使用x[0], x[1]
. 但是,我坚持rolling.apply()
阅读文档
DataFrame.rolling()和rolling.apply()
我认为使用'axis'
inrolling()
和'raw'
in apply
one 可以实现类似的行为。天真的方法
rol = df.rolling(window=2)
rol.apply(masscenter)
Run Code Online (Sandbox Code Playgroud)
逐行打印(将行数增加到窗口大小)
stamp
1900-01-01 02:59:47.000282 87.60
1900-01-01 03:00:01.042391 87.51
dtype: float64
Run Code Online (Sandbox Code Playgroud)
然后
stamp
1900-01-01 02:59:47.000282 739.0
1900-01-01 03:00:01.042391 10.0
dtype: float64
Run Code Online (Sandbox Code Playgroud)
因此,列masscenter
分别传递给(预期)。
可悲的是,在文档中几乎没有关于'axis'
. 然而,下一个变体显然是
rol = df.rolling(window=2, axis = 1)
rol.apply(masscenter)
Run Code Online (Sandbox Code Playgroud)
从不跟注masscenter
和加注ValueError in rol.apply(..)
> Length of passed values is 1, index implies 5
Run Code Online (Sandbox Code Playgroud)
我承认'axis'
由于缺乏文档,我不确定参数及其工作方式。这是问题的第一部分:
这里发生了什么?如何正确使用“轴”?它是为什么而设计的?
当然,之前有答案,即:
How-to-apply-a-function-to-two-columns-of-pandas-
dataframe 它适用于整个 DataFrame,而不是 Rolling。
How-to-invoke-pandas-rolling-apply-with-parameters-from-multiple-column
答案建议编写我自己的滚动函数,但对我来说罪魁祸首与评论中所问的相同 :如果需要使用怎么办'1T'
非统一时间戳的偏移窗口大小(例如)?
我不喜欢从头开始重新发明轮子的想法。此外,我想将熊猫用于所有内容,以防止从熊猫获得的套装与“自制卷”之间出现不一致。这个问题还有另一个答案,建议单独填充数据框并计算我需要的任何东西,但它不起作用:存储的数据的大小将是巨大的。这里提出了相同的想法:
Apply-rolling-function-on-pandas-dataframe-with-multiple-arguments
此处发布的另一个问答
Pandas-using-rolling-on-multiple-columns
它很好,最接近我的问题,但同样,不可能使用偏移窗口大小 ( window = '1T'
)。
在 pandas 1.0 出现之前询问了一些答案,鉴于文档可能会好得多,我希望现在可以同时滚动多个列。
问题的第二部分是: 是否有可能使用带有偏移窗口大小的 pandas 1.0.x 同时滚动多个列?
非常感谢。
小智 13
您可以使用numpy_ext模块中的rolling_apply函数:
import numpy as np
import pandas as pd
from numpy_ext import rolling_apply
def masscenter(price, nQty):
return np.sum(price * nQty) / np.sum(nQty)
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(df['stamp'], format='%H:%M:%S.%f')
df.set_index('stamp', inplace=True, drop=True)
window = 2
df['y'] = rolling_apply(masscenter, window, df.price.values, df.nQty.values)
print(df)
price nQty y
stamp
1900-01-01 02:59:47.000282 87.60 739 NaN
1900-01-01 03:00:01.042391 87.51 10 87.598798
1900-01-01 03:00:01.630182 87.51 10 87.510000
1900-01-01 03:00:01.635150 88.00 792 87.993890
1900-01-01 03:00:01.914104 88.00 10 88.000000
Run Code Online (Sandbox Code Playgroud)
adr*_*adr 12
这个怎么样:
def masscenter(ser):
print(df.loc[ser.index])
return 0
rol = df.price.rolling(window=2)
rol.apply(masscenter, raw=False)
Run Code Online (Sandbox Code Playgroud)
它使用滚动逻辑从任意列中获取子集。raw=False 选项为您提供这些子集的索引值(作为系列提供给您),然后您使用这些索引值从原始 DataFrame 中获取多列切片。
参考@saninstein 的出色回答。
从以下位置安装 numpy_ext: https: //pypi.org/project/numpy-ext/
import numpy as np
import pandas as pd
from numpy_ext import rolling_apply as rolling_apply_ext
def box_sum(a,b):
return np.sum(a) + np.sum(b)
df = pd.DataFrame({"x": [1,2,3,4], "y": [1,2,3,4]})
window = 2
df["sum"] = rolling_apply_ext(box_sum, window , df.x.values, df.y.values)
Run Code Online (Sandbox Code Playgroud)
输出:
print(df.to_string(index=False))
x y sum
1 1 NaN
2 2 6.0
3 3 10.0
4 4 14.0
Run Code Online (Sandbox Code Playgroud)
笔记
rolling_apply
为rolling_apply_ext
这样它就不可能干扰对 Pandas 的任何现有调用rolling_apply
(感谢 @LudoSchmidt 的评论)。顺便说一句,我放弃了使用 Pandas 的尝试。它从根本上被破坏了:它处理单列聚合并且应用时几乎没有问题,但当试图让它与更多两列或更多列一起工作时,它是一个过于复杂的鲁布-戈德堡机器。
归档时间: |
|
查看次数: |
13329 次 |
最近记录: |