pandas 扩展自定义聚合函数

问题描述 投票:0回答:2

我试图理解为什么这段代码会抛出错误。即使

expanding
之后的前 30 行是
np.nan
仍然应该允许数字运算。为什么会失败?我应该如何解决这个问题?

import pandas as pd
import numpy as np

i = pd.date_range('2000-01-01', '2000-06-01', freq='D')
x = pd.DataFrame(data=np.random.randint(0,10, (len(i), 3)), index = i, columns = list('abc'))
# this works
# x.expanding(min_periods=30).corr()
# this doesn't. Why? Is it because of nans? Isn't np.nan a float
x.expanding(min_periods=30).aggregate(lambda t: t.corr().stack().loc[[('a', 'b'), ('a', 'c')], :])
# this fails too
# x.expanding(min_periods=30).aggregate(lambda t: t+1)

DataError:没有要聚合的数字类型

我可以通过这段代码生成愿望输出:

y = x.expanding(min_periods=30).corr()
y.index.names = ['dates', 'letters']
y.columns.name = 'cols'
y=y.stack()
mi = pd.MultiIndex.from_tuples([('a','b'), ('a','c')], names = ['letters', 'cols'])
y.to_frame().join(pd.DataFrame(index=mi), on=['letters', 'cols'], how='inner')
python pandas group-by aggregate apply
2个回答
0
投票

将 expanding() 方法与 aggregate() 函数一起使用时代码失败的原因是前 29 行中存在 NaN 值,正如您所怀疑的那样。

当将 aggregate() 与 expanding() 方法一起使用时,Pandas 首先尝试创建一个包含窗口中所有值的 DataFrame。由于前 29 行有 NaN 值,聚合函数:

(lambda t: t.corr().stack().loc[[('a', 'b'), ('a', 'c')], :]

在这种情况下应用于包含 NaN 值的 DataFrame。这会导致错误。

NaN 值的存在会在执行数学运算或聚合函数时导致意外结果,这就是为什么最好在代码中显式处理它们。

要解决此问题,您可以在执行聚合之前使用 dropna() 方法删除包含 NaN 值的行:

x.expanding(min_periods=30).apply(lambda t:t.dropna().corr().stack().loc[[('a', 'b'), ('a', 'c')], :])

在这里,我们使用“apply()”方法而不是“aggregate()”,并首先通过在传递给 lambda 函数的 DataFrame“t”上调用“dropna()”来删除包含 NaN 值的行。然后我们计算相关矩阵并像以前一样堆叠结果。


0
投票

你可以试试这个:

out = (x.rename_axis("dates").expanding(min_periods=30).corr().xs("a", level=1)
           [["b", "c"]].dropna().melt(var_name="cols", ignore_index=False)
           .set_index("cols", append=True)
)

输出:

print(out)

                    value
dates      cols          
2000-01-30 b    -0.210288
2000-01-31 b    -0.223870
2000-02-01 b    -0.224411
2000-02-02 b    -0.156831
2000-02-03 b    -0.164199
...                   ...
2000-05-28 c     0.022239
2000-05-29 c     0.027344
2000-05-30 c     0.014873
2000-05-31 c     0.014310
2000-06-01 c     0.024398

[248 rows x 1 columns]
© www.soinside.com 2019 - 2024. All rights reserved.