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 的剪辑在某些情况下会在重新采样创建的块上崩溃的主要内容,如果未能解决你的问题,请参考以下文章

为啥在某些情况下会加密 WCF SoapFault 响应?

SQL 函数在某些情况下会出错,为啥?

用 memset() 写入的内存在不调用 free() 的情况下会在内存中保留多长时间?

__ldg 在某些情况下会导致执行时间变慢

IE 中单元格的 colspan 属性在某些情况下会影响 TABLE 元素的自动布局

在EXCEL中啥情况下会出现#num!,#name,#,#ref!等错误信息报告