Python循环生成time_of_day列异常:全列仅显示Morning求助
问题排查与解决:Pandas生成time_of_day列全部为Morning的问题
问题场景
尝试通过for循环+if语句给Pandas DataFrame新增time_of_day列,规则是:
- 6≤Hour≤12 → Morning
- 12<Hour≤17 → Afternoon
- 17<Hour≤22 → Evening
- 其余 → Night
但执行代码后,time_of_day列全是Morning,value_counts()只统计到1428条Morning。
错误代码
for i in range(len(df)): if df.loc[i, 'Hour'] >=6 & df.loc[i, 'Hour'] <= 12: df['time_of_day'] = "Morning" elif df.loc[i, 'Hour'] > 12 & df.loc[i, 'Hour'] <= 17: df['time_of_day'] == "Afternoon" elif df.loc[i, 'Hour'] > 17 & df.loc[i, 'Hour'] <= 22: df['time_of_day'] == "Evening" else: df['time_of_day'] = 'Night' df.time_of_day.value_counts()
错误原因分析
- 整列赋值而非单行赋值:每次循环直接给
df['time_of_day']赋值,会覆盖整个列的所有值。比如最后一次循环如果满足Morning的条件,整列就会被改成Morning,之前的赋值全部无效。应该用df.loc[i, 'time_of_day']指定单行赋值。 - 逻辑运算符错误:Python中逻辑与要用
and,&是位运算符,且未加括号时优先级会导致判断逻辑出错。正确写法应为(df.loc[i, 'Hour'] >=6) and (df.loc[i, 'Hour'] <=12)。 - 赋值运算符用错:elif分支里用了
==(比较判断)而非=(赋值),等于根本没给列赋值,即使条件满足也不会改变列的值。
修正后的for循环代码
# 先初始化列,避免赋值时出现缺失 df['time_of_day'] = '' for i in range(len(df)): hour = df.loc[i, 'Hour'] if 6 <= hour <= 12: df.loc[i, 'time_of_day'] = "Morning" elif 12 < hour <= 17: df.loc[i, 'time_of_day'] = "Afternoon" elif 17 < hour <= 22: df.loc[i, 'time_of_day'] = "Evening" else: df.loc[i, 'time_of_day'] = 'Night' df.time_of_day.value_counts()
更高效的Pandas原生实现(推荐)
Pandas不推荐用for循环处理数据,效率太低,用pd.cut或者np.select更简洁高效:
方法1:pd.cut
bins = [-float('inf'), 6, 12, 17, 22, float('inf')] labels = ['Night', 'Morning', 'Afternoon', 'Evening', 'Night'] df['time_of_day'] = pd.cut(df['Hour'], bins=bins, labels=labels, include_lowest=True) df.time_of_day.value_counts()
方法2:np.select
import numpy as np conditions = [ (df['Hour'] >=6) & (df['Hour'] <=12), (df['Hour'] >12) & (df['Hour'] <=17), (df['Hour'] >17) & (df['Hour'] <=22) ] choices = ['Morning', 'Afternoon', 'Evening'] df['time_of_day'] = np.select(conditions, choices, default='Night') df.time_of_day.value_counts()
内容的提问来源于stack exchange,提问作者Sami
相关产品推荐
相关产品推荐

