首页 > 其他 > 详细

Pandas系列教程(7)Pandas的SettingWithCopyWarning

时间:2020-10-21 14:30:18      阅读:49      评论:0      收藏:0      [点我收藏+]

Pandas的SettingWithCopyWarning

1、读取数据

import pandas as pd

file_path = "../datas/files/beijing_tianqi_2018.csv"
df = pd.read_csv(file_path)

# 替换温度的后缀℃, 并转为int32(修改列)
df.loc[:, bWendu] = df.loc[:, bWendu].str.replace(, ‘‘).astype(int32)
df.loc[:, yWendu] = df.loc[:, yWendu].str.replace(, ‘‘).astype(int32)

print(df.head(3))

 

2、复现

import pandas as pd

file_path = "../../datas/files/beijing_tianqi_2018.csv"
df = pd.read_csv(file_path)

# 替换温度的后缀℃, 并转为int32(修改列)
df.loc[:, bWendu] = df.loc[:, bWendu].str.replace(, ‘‘).astype(int32)
df.loc[:, yWendu] = df.loc[:, yWendu].str.replace(, ‘‘).astype(int32)
print(* * 25, 替换温度的后缀,并转为int类型, * * 25)
print(df.head(3))

# 只选出3月份的数据用于分析
condition = df[ymd].str.startswith(2018-03)
print(* * 25, 只选出3月份的数据用于分析, * * 25)
print(condition)

# 设置温差
print(* * 25, 设置温差, * * 25)
df[condition][wen_cha] = df[bWendu] - df[yWendu]

# 查看是否修改成功
print(* * 25, 查看是否修改成功, * * 25)
print(df[condition].head())

运行结果:

************************* 替换温度的后缀,并转为int类型 *************************
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1
************************* 只选出3月份的数据用于分析 *************************
0      False
1      False
2      False
3      False
4      False
       ...  
360    False
361    False
362    False
363    False
364    False
Name: ymd, Length: 365, dtype: bool
************************* 设置温差 *************************
************************* 查看是否修改成功 *************************
           ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
59  2018-03-01       8      -3     多云       西南风   1-2级   46       优         1
60  2018-03-02       9      -1   晴~多云        北风   1-2级   95       良         2
61  2018-03-03      13       3   多云~阴        北风   1-2级  214    重度污染         5
62  2018-03-04       7      -2   阴~多云       东南风   1-2级  144    轻度污染         3
63  2018-03-05       8      -3      晴        南风   1-2级   94       良         2
F:/Python_Projects/PythonDataAnalysis/4_Pandas/8_Pandas的SettingWithCopyWarning/8.1 复现/demo.py:19: 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
  df[condition][wen_cha] = df[bWendu] - df[yWendu]
原因:
发出警告的代码 df[condition][‘wen_cha‘] = df[‘bWendu‘] - df[‘yWendu‘]
相当于:df.get(condition).set(wen_cha), 第一步骤的get发出了警报
链式操作确实是两个步骤,先get后set,get得到的dataframe可能是view也可能是copy,pandas发出警告
核心要诀:pandas的dataframe的修改写操作,只允许在源dataframe上进行,一步到位

3、解决

解决方式1

import pandas as pd

file_path = "../../datas/files/beijing_tianqi_2018.csv"
df = pd.read_csv(file_path)

# 替换温度的后缀℃, 并转为int32(修改列)
df.loc[:, bWendu] = df.loc[:, bWendu].str.replace(, ‘‘).astype(int32)
df.loc[:, yWendu] = df.loc[:, yWendu].str.replace(, ‘‘).astype(int32)
print(* * 25, 替换温度的后缀,并转为int类型, * * 25)
print(df.head(3))

# 只选出3月份的数据用于分析
condition = df[ymd].str.startswith(2018-03)
print(* * 25, 只选出3月份的数据用于分析, * * 25)
print(condition)

# 设置温差
print(* * 25, 设置温差, * * 25)
# 将get + set的两步操作,改成set的一步操作
df.loc[condition, wen_cha] = df[bWendu] - df[yWendu]

# 查看是否修改成功
print(* * 25, 查看是否修改成功, * * 25)
print(df[condition].head())

解决方式2

import pandas as pd

file_path = "../../datas/files/beijing_tianqi_2018.csv"
df = pd.read_csv(file_path)

# 替换温度的后缀℃, 并转为int32(修改列)
df.loc[:, bWendu] = df.loc[:, bWendu].str.replace(, ‘‘).astype(int32)
df.loc[:, yWendu] = df.loc[:, yWendu].str.replace(, ‘‘).astype(int32)
print(* * 25, 替换温度的后缀,并转为int类型, * * 25)
print(df.head(3))

# 只选出3月份的数据用于分析
condition = df[ymd].str.startswith(2018-03)
print(* * 25, 只选出3月份的数据用于分析, * * 25)
print(condition)

# 设置温差
# 如果需要预筛选数据做后续的处理分析,使用copy赋值dataframe
print(* * 25, 设置温差, * * 25)
df_month3 = df[condition].copy()
print(df_month3.head())
df_month3[wen_cha] = df[bWendu] - df[yWendu]

# 查看是否修改成功
print(* * 25, 查看是否修改成功, * * 25)
print(df[condition].head())

总而言之,pandas不允许先筛选子dataframe,再进行修改写入

要么使用.loc实现一个步骤直接修改源dataframe

要么先复制一个子dataframe再一个步骤执行修改

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Pandas系列教程(7)Pandas的SettingWithCopyWarning

原文:https://www.cnblogs.com/xingxingnbsp/p/13851834.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!