Pandas SettingWithCopyWarning。我彻底糊涂了

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

当我运行以下代码段时,我得到了臭名昭著的pandas SettingWithCopyWarning。

for i in range(1, N):
    if df['deltaPressure'][i] < CLUSTER_THRESHOLD:
        df['Cluster'][i] = df['Cluster'][i-1]
    else:
        df['Cluster'][i] = df['Cluster'][i-1] + 1

我尝试通过添加一个.copy()来解决这个问题,如下所示。

for i in range(1, N):
    if df['deltaPressure'][i] < CLUSTER_THRESHOLD:
        df['Cluster'][i] = df['Cluster'][i-1].copy()
    else:
        df['Cluster'][i] = df['Cluster'][i-1].copy() + 1

不幸的是,我得到的警告没有变化。大量的google和搜索StackOverflow都没有让我更接近理解我的语法中的基本错误,或者我是如何无意中链的。代码似乎是正确运行的,但我讨厌忽略错误信息,希望它们将被证明是无关紧要的。

我将非常感激,无论是对我的代码的修正,还是对为什么.copy()对我没有好处的简单解释。

真诚地,并提前表示感谢。

Thomas Philips

python pandas chaining
1个回答
2
投票

问题是你使用的是 __setitem____getitem__ 同时。

  • df['Cluster'] : __getitem__
  • _[i] = __setitem__

如以下文件所解释 https:/tomaugspurger.github.iomodern-1-intro。, "大熊猫不能保证那第一只 获取项目 返回一个视图或底层数据的副本。将会对我上面调用的_的东西进行修改,结果是由 获取项目 在1.但我们不知道_与我们原来的记忆共享" df.

你应该使用 lociloc 来代替。

EDIT:重新阅读你的问题,我补充了另一种可能性,以实现你所做的事情,而不需要for循环。


import pandas as pd
import numpy as np
N = 100
CLUSTER_THRESHOLD = 50
df = pd.DataFrame({"deltaPressure": np.random.randint(1,100, N),
                   "Cluster": np.random.randint(1,5,N)})
df["top"] = df["deltaPressure"]<CLUSTER_THRESHOLD
df["Cluster"] = np.where(df["top"], df["Cluster"].shift(), df["Cluster"].shift() + 1)

希望能帮到你


0
投票

这的确是可行的--尽管我必须说,即使盯着它看了一会儿,它也一点也不直观。这似乎真的和Pandas的实现方式有关。有了你的建议和谷歌,我找到了一个全面的答案在 StackOverflow

谢谢你

© www.soinside.com 2019 - 2024. All rights reserved.