You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:36:01