Pandas 正确设置新列的方法,避免SettingWithCopyWarning警告

Pandas 正确设置新列的方法,避免SettingWithCopyWarning警告

在本文中,我们将介绍如何使用正确的方法设置新列,以避免在Pandas中遇到SettingWithCopyWarning警告。

阅读更多:Pandas 教程

背景

在Pandas中创建新列时,经常会遇到SettingWithCopyWarning警告。这个警告意味着变量被复制了,而不是按预期的方式分配新值。这通常会导致出现意外的结果和错误。

以下示例将演示如何使用不同方法创建新列:

import pandas as pd

df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = df1[df1['A'] > 1]
df2['C'] = 10
df2.loc[df2['B'] > 5, 'C'] = 20

df3 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df4 = df3[df3['A'] > 1].copy()
df4['C'] = 10
df4.loc[df4['B'] > 5, 'C'] = 20

print("df1:\n", df1)
print("df2:\n", df2)
print("df3:\n", df3)
print("df4:\n", df4)
Python

输出:

<ipython-input-2-cc41fd5b8b7f>:5: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  df2['C'] = 10
<ipython-input-2-cc41fd5b8b7f>:6: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  df2.loc[df2['B'] > 5, 'C'] = 20
df1:
    A  B
0  1  4
1  2  5
2  3  6
df2:
    A  B   C
1  2  5  10
2  3  6  20
df3:
    A  B
0  1  4
1  2  5
2  3  6
df4:
   A  B   C
1  2  5  10
2  3  6  20
Python

可以看出,df2和df4的结果是一样的,但df2会产生警告。这是因为df2是通过获取原始数据的切片而创建的,而df4是通过复制数据创建的。

方法

为了避免SettingWithCopyWarning,应使用以下两种方法之一:

方法一:使用.loc

.loc是Pandas中推荐的选择,因为它会明确地分配新值。

示例:

import pandas as pd

df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df.loc[df['A'] > 1, 'C'] = 10
df.loc[(df['A'] > 1) & (df['B'] > 5), 'C'] = 20
print(df)
Python

输出:

   A  B     C
0  1  4   NaN
1  2  5  10.0
2  3  6  20.0
Python

方法二:使用.copy()

使用.copy()方法可以创建副本。这种情况下,更改将在副本中进行,并且原始DataFrame不受影响。

示例:

import pandas aspd

df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = df1[df1['A'] > 1].copy()
df2['C'] = 10
df2.loc[df2['B'] > 5, 'C'] = 20
print("df1:\n", df1)
print("df2:\n", df2)
Python

输出:

df1:
    A  B
0  1  4
1  2  5
2  3  6
df2:
   A  B   C
1  2  5  10
2  3  6  20
Python

补充说明

  1. 如果您在嵌套方式中使用切片,在这种情况下,Pandas可能无法识别访问数据的方式并产生警告。因此,应该始终明确地使用.loc。

  2. 如果您在复制数据上进行修改,并且对原始数据没有影响,则可以使用.copy()。

总结

在Pandas中,应始终使用 .loc 和 .copy(),以避免出现SettingWithCopyWarning。这两种方法可以帮助您确定数据是否是副本或视图,并使代码更简洁、易于理解和维护。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册