Pandas 0.25.3 的剪辑在某些情况下会在重新采样创建的块上崩溃
Posted
技术标签:
【中文标题】Pandas 0.25.3 的剪辑在某些情况下会在重新采样创建的块上崩溃【英文标题】:Pandas 0.25.3's clip crashes in certain cases on chunks created by a resample 【发布时间】:2020-07-29 23:26:28 【问题描述】:关于 pandas 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)
我的 Python 版本是 3.7.6,pandas 是 0.25.3。
附带说明,它与迭代器配合得很好:
for entry, group in data.resample("30min"):
clip_low_at_0(x=group)
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
据我检查,这似乎发生了:
只有一定数量的值,即 2 个值没有问题,3 和 4 有问题,7 没有.. 只有特定的值组合。这个触发它,有些不会,有些会。 对于任何索引值,它似乎都不相关。 小组的位置很重要实际上,通过进一步挖掘,似乎由导致.clip()
错误的组生成的系列已损坏。尝试.copy()
它失败了,并且其他一些方法(如序列化方法)以错误结束。也许我没有正确使用 group 和 agg,但是还有另一种使用 pandas 来计算它的好方法吗?
困扰我的是它似乎在很多情况下都有效,而这种情况在 pandas>=1.0.0 中确实有效。
如果它碰巧是一个真正的错误,我当然会向 pandas 团队报告一个问题。 (编辑:熊猫似乎不鼓励旧版本的错误报告)
编辑:为了澄清,我想:
1) 知道它实际上是 groupby/agg 方面的误用还是实际错误
2) 如果有比自己制作剪辑更好的解决方法 (x.loc[x
【问题讨论】:
您能说出您的确切问题吗?您在寻找解决方法吗?为什么不能只使用迭代器方法? @amain 我刚刚更新了问题,明显的解决方法是手动进行剪辑,但我想知道我是否做得对,并希望保留组方法在索引管理方面的优势. 【参考方案1】:我可以重现您的问题,但似乎仅限于使用clip()
,不是吗? round()
等其他功能似乎运行良好。所以这在我看来绝对是 Pandas 的错误。
作为一般解决方法,您可以在聚合函数中直接使用 numpy 函数而不是 Pandas 函数:
def clip_low_at_0(x):
return numpy.clip(x, a_min=0, a_max=None).sum()
不过,为了完整起见:对于 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()
最后(你已经知道了):不需要在聚合函数中裁剪值,你可以预先将它应用到整个 DataFrame:
data.clip(lower=0).resample("30min").sum()
【讨论】:
感谢您的回答。它并不完全限于clip
,因为创建的Series
对象不是正确的对象(例如x.copy()
fails),因此其他方法可能会出现其他问题。但这似乎是一个棘手的错误,所以我对提供的解决方法很好:)(我之前无法剪辑,因为我实际上在我的程序中以编程方式应用了几个聚合函数,但是 numpy、手动剪辑或更高的限制会做) 以上是关于Pandas 0.25.3 的剪辑在某些情况下会在重新采样创建的块上崩溃的主要内容,如果未能解决你的问题,请参考以下文章
用 memset() 写入的内存在不调用 free() 的情况下会在内存中保留多长时间?