使用 iloc 后仍然得到 SettingWithCopyWarning。它从何而来?

时间:2021-01-27 21:39:10

标签: python pandas

我收到了 SettingWithCopyWarning 消息。

<块引用>

/usr/local/lib/python3.6/dist-packages/pandas/core/indexing.py:670: SettingWithCopyWarning: 试图在副本上设置一个值 来自 DataFrame 的切片

请参阅文档中的注意事项: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy iloc._setitem_with_indexer(indexer, value)

我已经尝试了几个小时,但无法找出问题所在。任何人都可以透露一点吗?

这是代码:

df = pd.read_excel(path).assign(rate = np.NaN, alert = np.NaN)

def incidence(data, treshold):

  #iterates through each row of dataset 
  for i, row in enumerate(df.itertuples()):
    try:
      #divides total_rdtpost by total_rdtused
      data.rate.iloc[i] = row[5]/row[7]
    except ZeroDivisionError:
      #fixes the ZeroDivisionError, please read https://docs.python.org/3/library/exceptions.html#ZeroDivisionError 
      data.rate.iloc[i] = 0.0
    #creates a low or high record depending on the treshold variable
    if data.rate.iloc[i] > treshold:
      data.alert.iloc[i] = "high"
    else:
      data.alert.iloc[i] = "low"

  return data

incidence(df, 0.2)

附注。我正在使用 Colab。

1 个答案:

答案 0 :(得分:0)

data.ratedata.alert 分别是 data['rate']data['alert'] 的缩写。 data['rate'] 可以被复制,这样做data['rate'].iloc[i]仍然是复制品。

将它们更改为:

data.iloc[i, data.columns.get_loc('rate')] = ...

并且您可以预先保存列索引:

def incidence(data, treshold):
    # at the start of the function
    rate_col = data.columns.get_loc('rate')
    alert_col = data.columns.get_loc('alert')
    ...
    for ...
        # later
        data.iloc[i, rate_col] = ...

顺便说一句,您的 for 循环引用了全局/外部 df 而不是传递给函数的 data。应该是:

for i, row in enumerate(data.itertuples()):

还有一点,你可以把函数中的所有步骤都作为列操作来做,而不是使用itertuples。无论如何,您正在修改函数中的数据框。