如何将长度不同的Pandas Series按DataFrame指定列索引匹配添加为新列
问题
我有一个700多行的DataFrame,还有一个28行的Series(s_conditions)。想要根据DataFrame里的**"Reason for absence"**列的数值,匹配Series的索引,把Series的对应值作为新列添加到DataFrame中。
我试过用df1.insert(loc=0, column="Reason_for_absence", value=s_conditions),但结果不对:只有前28行有值,而且匹配关系完全错误,28行之后全是NaN。需要实现所有行都按索引正确匹配的效果。
数据示例
DataFrame示例
ID Reason for absence Month of absence Day of the week Seasons 0 11 26 7 3 1 1 36 0 7 3 1 2 3 23 7 4 1 3 7 7 7 5 1 4 11 23 7 5 1 5 3 23 7 6 1 6 10 22 7 6 1 7 20 23 7 6 1 8 14 19 7 2 1 9 1 22 7 2 1 10 20 1 7 2 1 11 20 1 7 3 1 12 20 11 7 4 1 13 3 11 7 4 1 14 3 23 7 4 1 15 24 14 7 6 1 16 3 23 7 6 1 17 3 21 7 2 1 18 6 11 7 5 1 19 33 23 8 4 1 20 18 10 8 4 1 21 3 11 8 2 1 22 10 13 8 2 1 23 20 28 8 6 1 24 11 18 8 2 1 25 10 25 8 2 1 26 11 23 8 3 1 27 30 28 8 4 1 28 11 18 8 4 1 29 3 23 8 6 1 30 3 18 8 2 1 31 2 18 8 5 1 32 1 23 8 5 1 33 2 18 8 2 1 34 3 23 8 2 1 35 10 23 8 2 1 36 11 24 8 3 1 37 19 11 8 5 1 38 2 28 8 6 1 39 20 23 8 6 1 40 27 23 9 3 1 41 34 23 9 2 1 42 3 23 9 3 1 43 5 19 9 3 1 44 14 23 9 4 1
Series(s_conditions)示例
0 Not absent 1 Infectious and parasitic diseases 2 Neoplasms 3 Diseases of the blood 4 Endocrine, nutritional and metabolic diseases 5 Mental and behavioural disorders 6 Diseases of the nervous system 7 Diseases of the eye 8 Diseases of the ear 9 Diseases of the circulatory system 10 Diseases of the respiratory system 11 Diseases of the digestive system 12 Diseases of the skin 13 Diseases of the musculoskeletal system 14 Diseases of the genitourinary system 15 Pregnancy and childbirth 16 Conditions from perinatal period 17 Congenital malformations 18 Symptoms not elsewhere classified 19 Injury 20 External causes 21 Factors influencing health status 22 Patient follow-up 23 Medical consultation 24 Blood donation 25 Laboratory examination 26 Unjustified absence 27 Physiotherapy 28 Dental consultation dtype: object
错误输出示例
Reason_for_absence ID Reason for absence \ 0 Not absent 11 26 1 Infectious and parasitic diseases 36 0 2 Neoplasms 3 23 3 Diseases of the blood 7 7 4 Endocrine, nutritional and metabolic diseases 11 23 5 Mental and behavioural disorders 3 23 6 Diseases of the nervous system 10 22 7 Diseases of the eye 20 23 8 Diseases of the ear 14 19 9 Diseases of the circulatory system 1 22 10 Diseases of the respiratory system 20 1 11 Diseases of the digestive system 20 1 12 Diseases of the skin 20 11 13 Diseases of the musculoskeletal system 3 11 14 Diseases of the genitourinary system 3 23 15 Pregnancy and childbirth 24 14 16 Conditions from perinatal period 3 23 17 Congenital malformations 3 21 18 Symptoms not elsewhere classified 6 11 19 Injury 33 23 20 External causes 18 10 21 Factors influencing health status 3 11 22 Patient follow-up 10 13 23 Medical consultation 20 28 24 Blood donation 11 18 25 Laboratory examination 10 25 26 Unjustified absence 11 23 27 Physiotherapy 30 28 28 Dental consultation 11 18 29 NaN 3 23 30 NaN 3 18 31 NaN 2 18 32 NaN 1 23
错误原因
你用insert直接传入Series时,是按DataFrame的行索引去匹配Series的行索引,而非用DataFrame中"Reason for absence"列的数值匹配Series的索引。这就导致前28行是按位置强行对应,后续行因Series无对应索引出现NaN,且匹配逻辑完全错误。
解决方案
核心是用DataFrame的"Reason for absence"列去索引Series,获取对应值后作为新列添加,以下是两种常用实现方式:
方式1:直接赋值添加新列
# 生成匹配后的对应值,添加为新列 df1["Reason_for_absence"] = df1["Reason for absence"].map(s_conditions)
如果需要将新列插入到指定位置(比如第0列),可先赋值再调整列顺序:
df1["Reason_for_absence"] = df1["Reason for absence"].map(s_conditions) # 将新列移至第0位 df1 = df1[["Reason_for_absence"] + [col for col in df1.columns if col != "Reason_for_absence"]]
方式2:结合insert实现指定位置插入
若一定要用insert,先通过索引匹配得到完整结果数组,再传入insert:
# 先获取所有行的匹配值 matched_values = df1["Reason for absence"].map(s_conditions) # 插入到第0列 df1.insert(loc=0, column="Reason_for_absence", value=matched_values)
效果验证
比如第0行"Reason for absence"为26,对应Series索引26的值是"Unjustified absence";第1行值为0,对应"Not absent",以此类推,所有行都会正确匹配,不会出现NaN(只要DataFrame中"Reason for absence"的数值都在Series的索引范围内)。
内容的提问来源于stack exchange,提问作者Aarav

