遍历DataFrame的Age列用if-else分组创建新列Age in Num失败求助
问题:DataFrame新列赋值错误,所有值均为36
问题背景
我的dataset['Age']列的value_counts()输出如下:
36-55-MATURED VOTER 492 24-35-YOUNG VOTER 341 56 Above-EXPERIENCED VOTER 182 18-23-NEW VOTER 77 70 5 60 5 68 4 65 3 63 3 62 3 75 3 72 1 69 1 67 1 80 1 73 1 66 1 Name: Age, dtype: int64
我想在同一个DataFrame里创建新列dataset['Age in Num'],按以下规则映射原列值:
18-23-NEW VOTER映射为1824-35-YOUNG VOTER映射为2436-55-MATURED VOTER映射为36- 其余所有值映射为56
但我用了下面的代码后,dataset['Age in Num']的所有值都变成了36,求帮忙解决:
for Age in dataset['Age']: if Age == '24-35-YOUNG VOTER': dataset['Age in Num'] = 24 elif Age == '36-55-MATURED VOTER': dataset['Age in Num'] = 36 elif Age == '18-23-NEW VOTER': dataset['Age in Num'] = 18 else: dataset['Age in Num'] = 56
问题原因
你写的循环犯了一个典型的错误:每次循环都直接给整列赋值,而不是给当前行的对应位置赋值。
举个例子,当循环到第一个是36-55-MATURED VOTER的行时,你执行dataset['Age in Num'] = 36,这会把整个Age in Num列的所有值都改成36。之后循环到其他行时,虽然会执行其他赋值语句,但最后循环结束时,只要最后一次循环的行是36-55-MATURED VOTER,整列就会被覆盖成36——这就是为什么你看到所有值都是36的原因。
解决方案
方法1:使用map函数(推荐,简洁高效)
先创建一个映射字典,然后用map方法直接生成新列,不在字典里的值用fillna填充为56:
age_mapping = { '18-23-NEW VOTER': 18, '24-35-YOUNG VOTER': 24, '36-55-MATURED VOTER': 36 } dataset['Age in Num'] = dataset['Age'].map(age_mapping).fillna(56).astype(int)
方法2:使用apply函数
自定义一个映射函数,用apply对每一行的Age值进行判断:
def map_age(age): if age == '18-23-NEW VOTER': return 18 elif age == '24-35-YOUNG VOTER': return 24 elif age == '36-55-MATURED VOTER': return 36 else: return 56 dataset['Age in Num'] = dataset['Age'].apply(map_age)
方法3:修正原来的循环(不推荐,效率较低)
如果你一定要用循环实现,需要定位到当前行的索引,给对应位置赋值,同时先初始化新列的默认值:
# 先把新列初始化为默认值56 dataset['Age in Num'] = 56 # 遍历每一行的索引和Age值 for idx, age in dataset['Age'].items(): if age == '24-35-YOUNG VOTER': dataset.loc[idx, 'Age in Num'] = 24 elif age == '36-55-MATURED VOTER': dataset.loc[idx, 'Age in Num'] = 36 elif age == '18-23-NEW VOTER': dataset.loc[idx, 'Age in Num'] = 18
内容的提问来源于stack exchange,提问作者ravsab551955
相关产品推荐
相关产品推荐

