我正在编写一个代码,将滚动窗口应用于返回多列的函数。
输入:熊猫系列
预期输出:3列数据帧
def fun1(series, ):
# Some calculations producing numbers a, b and c
return {"a": a, "b": b, "c": c}
res.rolling('21 D').apply(fun1)
res的内容:
time
2019-09-26 16:00:00 0.674969
2019-09-26 16:15:00 0.249569
2019-09-26 16:30:00 -0.529949
2019-09-26 16:45:00 -0.247077
2019-09-26 17:00:00 0.390827
...
2019-10-17 22:45:00 0.232998
2019-10-17 23:00:00 0.590827
2019-10-17 23:15:00 0.768991
2019-10-17 23:30:00 0.142661
2019-10-17 23:45:00 -0.555284
Length: 1830, dtype: float64
错误:
TypeError: must be real number, not dict
我尝试过的:
我还浏览了SO中的许多相关帖子,以陈述以下几点:
但是指定的解决方案都没有解决这个问题。
有没有直接的解决办法?
这个黑客似乎为我工作,尽管滚动的附加功能不能应用于这个解决方案。然而,由于多重处理,应用程序的速度明显更快。
from multiprocessing import Pool
import functools
def apply_fn(indices, fn, df):
return fn(df.loc[indices])
def rolling_apply(df, fn, window_size, start=None, end=None):
"""
The rolling application of a function fn on a DataFrame df given the window_size
"""
x = df.index
if start is not None:
x = x[x >= start]
if end is not None:
x = x[x <= end]
if type(window_size) == str:
delta = pd.Timedelta(window_size)
index_sets = [x[(x > (i - delta)) & (x <= i)] for i in x]
else:
assert type(window_size) == int, "Window size should be str (representing Timedelta) or int"
delta = window_size
index_sets = [x[(x > (i - delta)) & (x <= i)] for i in x]
with Pool() as pool:
result = list(pool.map(functools.partial(apply_fn, fn=fn, df=df), index_sets))
result = pd.DataFrame(data=result, index=x)
return result
在具备上述功能后,插入该功能以滚动到自定义的rolling\u功能中
。
result = rolling_apply(res, fun1, "21 D")
结果内容:
a b c
time
2019-09-26 16:00:00 NaN NaN NaN
2019-09-26 16:15:00 0.500000 0.106350 0.196394
2019-09-26 16:30:00 0.500000 0.389759 -0.724829
2019-09-26 16:45:00 2.000000 0.141436 -0.529949
2019-09-26 17:00:00 6.010184 0.141436 -0.459231
... ... ... ...
2019-10-17 22:45:00 4.864015 0.204483 -0.761609
2019-10-17 23:00:00 6.607717 0.204647 -0.761421
2019-10-17 23:15:00 7.466364 0.204932 -0.761108
2019-10-17 23:30:00 4.412779 0.204644 -0.760386
2019-10-17 23:45:00 0.998308 0.203039 -0.757979
1830 rows × 3 columns
注:
window_size
只考虑最大窗口大小,因此window_size
下面的所有起始索引将使其窗口包括所有元素直到起始元素。pool.map
不能接受本地或lambda函数,因为它们不能根据多重处理
库下面是一个使用滚动
生成数据帧的老套答案:
import pandas as pd
import numpy as np
dr = pd.date_range('09-26-2019', '10-17-2019', freq='15T')
data = np.random.rand(len(dr))
s = pd.Series(data, index=dr)
output = pd.DataFrame(columns=['a','b','c'])
row = 0
def compute(window, df):
global row
a = window.max()
b = window.min()
c = a - b
df.loc[row,['a','b','c']] = [a,b,c]
row+=1
return 1
s.rolling('1D').apply(compute,kwargs={'df':output})
output.index = s.index
似乎rolling
apply
函数总是希望返回一个数字,以便根据计算立即生成一个新的序列。
我通过创建一个新的output
DataFrame(带有所需的输出列)并在函数中写入它来解决这个问题。我不确定是否有办法在滚动对象中获取索引,因此我改为使用global
来增加写入新行的次数。不过,鉴于上述观点,您需要返回一些数字。因此,当实际的
滚动
操作返回一系列1
时,输出
被修改:
In[0]:
s
Out[0]:
2019-09-26 00:00:00 0.106208
2019-09-26 00:15:00 0.979709
2019-09-26 00:30:00 0.748573
2019-09-26 00:45:00 0.702593
2019-09-26 01:00:00 0.617028
2019-10-16 23:00:00 0.742230
2019-10-16 23:15:00 0.729797
2019-10-16 23:30:00 0.094662
2019-10-16 23:45:00 0.967469
2019-10-17 00:00:00 0.455361
Freq: 15T, Length: 2017, dtype: float64
In[1]:
output
Out[1]:
a b c
2019-09-26 00:00:00 0.106208 0.106208 0.000000
2019-09-26 00:15:00 0.979709 0.106208 0.873501
2019-09-26 00:30:00 0.979709 0.106208 0.873501
2019-09-26 00:45:00 0.979709 0.106208 0.873501
2019-09-26 01:00:00 0.979709 0.106208 0.873501
... ... ...
2019-10-16 23:00:00 0.980544 0.022601 0.957943
2019-10-16 23:15:00 0.980544 0.022601 0.957943
2019-10-16 23:30:00 0.980544 0.022601 0.957943
2019-10-16 23:45:00 0.980544 0.022601 0.957943
2019-10-17 00:00:00 0.980544 0.022601 0.957943
[2017 rows x 3 columns]
这感觉更像是一个
滚动
的漏洞,而不是预期的用途,所以我有兴趣看到一个更优雅的答案。
更新:感谢@JuanPi,您可以使用此答案获得滚动窗口索引。所以一个非
全局的
答案可以是这样的:
def compute(window, df):
a = window.max()
b = window.min()
c = a - b
df.loc[window.index.max(),['a','b','c']] = [a,b,c]
return 1
我想基于多个条件的评估创建一系列新的逻辑值。 举个例子 然而,我想返回一个逻辑序列,即。 如果可能的话,我想用熊猫的方法。
问题内容: 我正在使用以下df: 我想在所有年份中强制使用数字: 有没有简单的方法可以做到这一点,还是我必须全部输入? 问题答案: 更新: 您以后不需要转换值,可以在读取CSV时 即时 进行: 如果您需要将多列转换为数字dtypes,请使用以下技术: 样本来源DF: 将选定的列转换为数字dtypes: PS,如果要选择 所有 ()列,请使用以下简单技巧:
问题内容: 我有一个包含多个列的数据集,我希望对其进行一次热编码。但是,我不想为每个编码都有编码,因为所说的列与所说的项目有关。我想要的是一组使用所有列的虚拟变量。请参阅我的代码以获得更好的解释。 假设我的数据框如下所示: 如果我执行 输出将是 但是,我想获得的是这样的东西: 代替具有表示编码,例如多列的和,我只希望有一组(,,等等)与值时任何在列中的值的,,显示出来。 需要说明的是,在我的原始数
获取熊猫
问题内容: 支持多级列名: 此功能非常有用,因为它允许“水平”地将同一数据框的多个版本附加到区分实例的列名称的第一级(在我的示例中)。 想象一下我已经有一个这样的数据框: 有没有一种好方法可以向列名添加另一个级别,类似于行索引: 问题答案: 无需创建元组列表 采用: 结果数据框: 2014年1月25日起提出要求