尝试使用.loc [row_indexer,col_indexer] = value,即使在使用正式版之后也会发出警告

时间:2015-09-14 20:34:30

标签: python pandas

这是我的代码中的一行,我得到了SettingWithCopyWarning:

value1['Total Population']=value1['Total Population'].replace(to_replace='*', value=4)

然后我改为:

row_index= value1['Total Population']=='*'
value1.loc[row_index,'Total Population'] = 4

这仍然给出了相同的警告。我该如何摆脱它?

另外,对于我使用的 convert_objects(convert_numeric = True)函数,我收到相同的警告,有没有办法避免这种情况。

 value1['Total Population'] = value1['Total Population'].astype(str).convert_objects(convert_numeric=True)

这是我收到的警告信息:

正在尝试在DataFrame的切片副本上设置值。 尝试使用.loc [row_indexer,col_indexer] = value而不是

请参阅文档中的警告:http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

6 个答案:

答案 0 :(得分:9)

如果您使用 .loc[row,column] 仍然出现相同的错误,可能是因为复制了另一个数据框。您必须使用 .copy()

这是一步一步的错误再现:

import pandas as pd

d = {'col1': [1, 2, 3, 4], 'col2': [3, 4, 5, 6]}
df = pd.DataFrame(data=d)
df
#   col1    col2
#0  1   3
#1  2   4
#2  3   5
#3  4   6

创建一个新列并更新其值:

df['new_column'] = None
df.loc[0, 'new_column'] = 100
df
#   col1    col2    new_column
#0  1   3   100
#1  2   4   None
#2  3   5   None
#3  4   6   None

我没有收到错误。但是,让我们根据前一个数据框创建另一个数据框:

new_df = df.loc[df.col1>2]
new_df
#col1   col2    new_column
#2  3   5   None
#3  4   6   None

现在,使用 .loc,我将尝试以相同的方式替换一些值:

new_df.loc[2, 'new_column'] = 100

然而,我又收到了这个可恶的警告:

<块引用>

正在尝试在来自 DataFrame 的切片副本上设置值。尝试 使用 .loc[row_indexer,col_indexer] = value 代替

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

解决方案

在创建新数据框时使用 .copy() 将解决警告:

new_df = df.loc[df.col1>2].copy()
new_df.loc[2, 'new_column'] = 100

现在,您不会收到任何警告!

如果您的数据框是在另一个数据框之上使用过滤器创建的,请始终使用 .copy()

答案 1 :(得分:1)

您是否尝试过直接设置?:

value1.loc[value1['Total Population'] == '*', 'Total Population'] = 4

答案 2 :(得分:1)

得到解决方案:

我创建了一个新的DataFrame,并且只存储了我需要处理的列的值,它现在没有给我任何错误!

奇怪,但工作。

答案 3 :(得分:1)

我不知道这对数据存储/内存的影响有多严重,但它每次都会针对您的平均数据帧进行修复:

def addCrazyColFunc(df):
    dfNew = df.copy()
    dfNew['newCol'] = 'crazy'
    return dfNew

就像消息中说的那样...进行复印,您就可以开始了。如果有人可以解决以上问题而没有副本,请发表评论。以上所有loc内容在这种情况下均不起作用。

答案 4 :(得分:1)

我之所以来到这里,是因为我想根据另一列中的值有条件地设置新列的值。

对我有用的是numpy.where:

import numpy as np
import pandas as pd
...

df['Size'] = np.where((df.value > 10), "Greater than 10", df.value)

答案 5 :(得分:0)

我能够避免使用以下语法发出相同的警告消息:

{{1}}

请注意,无需将数据框重新分配给自身,即 value1 ['Total Population'] = value1 ['Total Population'] ...