如何用.loc[]修改子集与日期处理以消除SettingWithCopyWarning?
解决Pandas SettingWithCopyWarning警告问题
警告原因
出现SettingWithCopyWarning的核心原因是:当你通过切片(布尔索引、列选择等)得到DataFrame的子集时,Pandas无法确定这个子集是原数据的视图(和原数据共享内存)还是副本(独立内存)。直接给这类子集赋值时,可能导致原数据意外修改或修改不生效,因此Pandas抛出警告提醒规范操作。
分步修正方案
1. 第一次警告(处理Date列时)
原代码中筛选2023年数据后,df是原DataFrame的切片视图,后续修改Date列触发警告。
- 修改点1:筛选数据时显式创建副本,确保
df是独立对象:# 原代码 df = df[df["Date"].str.contains("2023") == True] # 修改为 df = df[df["Date"].str.contains("2023")].copy() - 修改点2:用Pandas内置的
pd.to_datetime替代apply+lambda处理日期,更高效简洁:# 原代码 df["Date"] = df["Date"].apply(lambda x: datetime.strptime(str(x), "%d-%m-%Y")) # 修改为 df["Date"] = pd.to_datetime(df["Date"], format="%d-%m-%Y")
2. 第二次警告(给df_XRL添加Month/Week day列时)
df_XRL是从df切片得到的子集,同样需要显式创建副本:
- 修改点1:创建
df_XRL时添加.copy():# 原代码 df_XRL = df[df["Control Point"].str.contains("Heung Yuen Wai") & df["Arrival / Departure"].str.contains("Departure")] # 修改为 df_XRL = df[df["Control Point"].str.contains("Heung Yuen Wai") & df["Arrival / Departure"].str.contains("Departure")].copy() - 修改点2:用Datetime列的
dt属性提取月份和星期,无需手动创建DatetimeIndex:# 原代码 df_XRL['Month'] = pd.DatetimeIndex(df_XRL['Date']).strftime("%b") df_XRL['Week day'] = pd.DatetimeIndex(df_XRL['Date']).strftime("%a") # 修改为 df_XRL['Month'] = df_XRL['Date'].dt.strftime("%b") df_XRL['Week day'] = df_XRL['Date'].dt.strftime("%a")
完整修正后代码
import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline # 读取香港入境处口岸旅客数据 df = pd.read_csv("https://www.immd.gov.hk/opendata/eng/transport/immigration_clearance/statistics_on_daily_passenger_traffic.csv") # 移除最后一列无效数据,筛选2023年数据并创建独立副本 df = df.iloc[:, :-1] df = df[df["Date"].str.contains("2023")].copy() # 转换日期格式为Datetime类型 df["Date"] = pd.to_datetime(df["Date"], format="%d-%m-%Y") # 筛选指定重点口岸数据 options = ['Airport', 'Express Rail Link West Kowloon', 'Lo Wu', 'Lok Ma Chau Spur Line', 'Heung Yuen Wai', 'Hong Kong-Zhuhai-Macao Bridge', 'Shenzhen Bay'] df_clean = df.loc[df['Control Point'].isin(options)] # 筛选香园围口岸离港的香港居民数据,创建独立副本 df_XRL = df[df["Control Point"].str.contains("Heung Yuen Wai") & df["Arrival / Departure"].str.contains("Departure")].copy() df_XRL = df_XRL[["Date","Hong Kong Residents"]] # 提取月份缩写和星期缩写 df_XRL['Month'] = df_XRL['Date'].dt.strftime("%b") df_XRL['Week day'] = df_XRL['Date'].dt.strftime("%a") # 按月份和星期汇总数据并可视化 monthOrder = ['Jan', 'Feb', 'Mar', 'Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] dayOrder = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'] pivot_XRL = pd.pivot_table(df_XRL, index=['Month'], values=['Hong Kong Residents'], columns=['Week day'], aggfunc=('sum')).loc[monthOrder, (slice(None), dayOrder)] pivot_XRL.plot(figsize = (20,8)) plt.grid() plt.legend(loc='best'); plt.xlabel('Month',fontsize=15) plt.ylabel('Persons',fontsize=15) plt.rc('xtick',labelsize=15) plt.rc('ytick',labelsize=15) plt.legend(fontsize="x-large")
内容的提问来源于stack exchange,提问作者ronzenith
相关产品推荐
相关产品推荐

