带datetime索引的DataFrame操作触发SettingWithCopyWarning求解决方案
你遇到的SettingWithCopyWarning本质是当前操作的DataFrame是其他DataFrame的切片视图,而非独立对象。你可以在最初生成该DataFrame的步骤末尾添加.copy(),即可从根源消除该警告,示例如下:
# 假设你原本是从全量数据筛选得到当前df,添加.copy()即可 df = df_all[df_all['hour'].notna()].copy()
你目前手写for循环遍历赋值的写法完全没必要,pandas自带的向量化操作可以实现相同需求,同时兼容所有索引类型(包括你使用的datetime索引),执行效率远高于手写遍历,也不会触发链式索引警告:
方案1:一键生成所有时段的0-1标识列
你写的4个for循环可以直接替换为pd.get_dummies的单行实现:
def get_part_of_day(hour): return ( "morning" if 5 <= hour <= 11 else "afternoon" if 12 <= hour <= 17 else "evening" if 18 <= hour <= 22 else "night" ) df['part_of_day'] = df['hour'].map(get_part_of_day) # 以下代码替代所有for循环,直接生成四个时段的0-1列 df = pd.concat([df, pd.get_dummies(df['part_of_day'], dtype=int)], axis=1)
方案2:单独生成单个时段的标识列
如果不需要同时生成所有时段的列,可以用布尔判断直接转整数:
df['morning'] = (df['part_of_day'] == 'morning').astype(int) df['afternoon'] = (df['part_of_day'] == 'afternoon').astype(int) # 其余列写法以此类推
兼容遍历写法(不推荐,仅作说明)
如果你确实需要按行遍历操作,datetime索引也可以通过iloc按位置访问,不需要手动处理索引值:
for i in range(len(df)): df.iloc[i, df.columns.get_loc('morning')] = 1 if df.iloc[i, df.columns.get_loc('part_of_day')] == 'morning' else 0
内容的提问来源于stack exchange,提问作者SonnePer
相关产品推荐
相关产品推荐

