Tan*_*och 4 python debugging time-series pandas pandas-groupby
关于熊猫 0.25.3 中基于时间的 groupby 的结果,我有一个非常狭窄的问题。
我正在编写一个库来执行各种基于时间的聚合,并在非常特定的情况下遇到了可能是错误的问题。它不会发生在 pandas>=1 中,但如果可能的话,我希望仍然能够支持 pandas 0.25.3(它仍然与我们的用户相关)。
以下情况我缩小了范围,导致“pandas/core/internals/blocks.py in where”中异常捕获的无限循环,最终导致python崩溃,退出代码为 134 :
import pandas as pd
data = pd.DataFrame(
data=[15.0, 0.0, 0.0, -10.0, 0.0],
index=pd.to_datetime(
[
"2018-01-01 00:00:00.000000",
"2018-01-01 00:25:00.000000",
"2018-01-01 00:30:00.000000",
"2018-01-01 00:31:00.000000",
"2018-01-01 00:47:00.000000",
]
)
)
def clip_low_at_0(x):
return x.clip(lower=0).sum()
data.resample("30min").agg(clip_low_at_0)
Run Code Online (Sandbox Code Playgroud)
我的 Python 版本是 3.7.6,pandas 0.25.3。
作为旁注,它适用于迭代器:
for entry, group in data.resample("30min"):
clip_low_at_0(x=group)
Run Code Online (Sandbox Code Playgroud)
并且data.groupby(pd.Grouper(freq="30min"))有完全相同的问题。
导致问题的组是这个(第二个):
0
2018-01-01 00:30:00 0.0
2018-01-01 00:31:00 -10.0
2018-01-01 00:47:00 0.0
Run Code Online (Sandbox Code Playgroud)
据我检查,这似乎发生了:
实际上,通过进一步挖掘,似乎导致错误的组生成的系列.clip()已损坏。尝试.copy()失败,其他一些方法(如序列化方法)以错误结尾。也许我没有正确使用 group 和 agg,但是还有另一种使用熊猫来计算这个的好方法吗?
困扰我的是它似乎在很多情况下都有效,而这个确切的情况在 pandas>=1.0.0 中有效。
如果它恰好是一个真正的错误,我当然会在问题中向 Pandas 的团队报告。(编辑:熊猫似乎不鼓励旧版本的错误报告)
编辑:为了澄清,我想:
1) 知道它是否真的是误用或 groupby/agg 方面的实际错误
2) 如果有比自己剪辑更好的解决方法 (x.loc[x < 0] = 0)。因为这个组将来可能会导致其他用于聚合的函数出现其他问题。如果可能的话,我想保持重采样方法不必自己处理索引,实际上我使用相同的结构进行了一些其他聚合。
我可以重现您的问题,但似乎仅限于使用clip(),不是吗?其他功能如round()etc 似乎运行良好。所以这对我来说绝对是 Pandas 的 bug。
作为一般解决方法,您可以在聚合函数中直接使用numpy函数而不是 Pandas 函数:
def clip_low_at_0(x):
return numpy.clip(x, a_min=0, a_max=None).sum()
Run Code Online (Sandbox Code Playgroud)
尽管如此,为了完整起见:针对Pandas 的错误行为的特定解决方法(也是一个奇怪的解决方法)clip()是明确设置上限。虽然我还没有理解为什么会这样,但实际上确实如此(至少在这里):
def clip_low_at_0(x):
# using numpy's 'double' dtype max value here, but this could
# be replaced with sys.maxsize or any other sensible constant
maxval = numpy.finfo('d').max
return x.clip(lower=0, upper=maxval).sum()
Run Code Online (Sandbox Code Playgroud)
最后(你已经知道了):不需要在聚合函数中裁剪值,你可以预先将它应用到整个 DataFrame:
data.clip(lower=0).resample("30min").sum()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
162 次 |
| 最近记录: |