为带自定义索引的DataFrame使用apply生成新列时出现NaN问题求助
自定义索引DataFrame使用apply生成新列全为NaN的问题解决
问题原因
你遇到的NaN问题核心是索引不匹配:
当你通过pd.DataFrame(df_test.apply(...).tolist())生成新数据时,这个新DataFrame默认使用从0开始的整数索引;而原df的索引是自定义的a1、b1、c1、d1、e1。pandas在列赋值时会严格按索引对齐,两边索引完全不对应,所以新列只能填充NaN。
解决方案
方法1:跳过索引匹配,直接赋值数值
直接提取新DataFrame的数值部分(忽略索引)进行赋值,代码最简单:
import pandas as pd def calc_test(row): a = row['col1'] + row['col2'] b = row['col1'] / row['col2'] return (a, b) df_test_dict={'col1':[1,2,3,4,5],'col2':[10,20,30,40,50]} df_test=pd.DataFrame(df_test_dict) df_test.index=['a1','b1','c1','d1','e1'] # 修改后的赋值代码 df_test[['a','b']] = pd.DataFrame(df_test.apply(calc_test, axis=1).tolist()).values
或者更简洁的写法:
df_test[['a','b']] = list(df_test.apply(calc_test, axis=1))
方法2:让apply返回Series,自动对齐索引
修改calc_test函数,让它返回带指定列名的Series,这样apply的结果会自动继承原df的索引,直接赋值即可:
import pandas as pd def calc_test(row): a = row['col1'] + row['col2'] b = row['col1'] / row['col2'] # 返回Series,指定列名 return pd.Series([a, b], index=['a', 'b']) df_test_dict={'col1':[1,2,3,4,5],'col2':[10,20,30,40,50]} df_test=pd.DataFrame(df_test_dict) df_test.index=['a1','b1','c1','d1','e1'] # 直接赋值,索引自动对齐 df_test[['a','b']] = df_test.apply(calc_test, axis=1)
方法3:重置原索引后赋值,再恢复
如果需要保留原索引,也可以先重置为整数索引,赋值后再恢复原索引:
import pandas as pd def calc_test(row): a = row['col1'] + row['col2'] b = row['col1'] / row['col2'] return (a, b) df_test_dict={'col1':[1,2,3,4,5],'col2':[10,20,30,40,50]} df_test=pd.DataFrame(df_test_dict) df_test.index=['a1','b1','c1','d1','e1'] # 保存原索引 original_index = df_test.index # 重置索引为整数 df_test = df_test.reset_index(drop=True) # 赋值 df_test[['a','b']] = pd.DataFrame(df_test.apply(calc_test, axis=1).tolist()) # 恢复原索引 df_test.index = original_index
验证结果
执行任意一种方法后,df_test的结果都会变为:
| col1 | col2 | a | b | |
|---|---|---|---|---|
| a1 | 1 | 10 | 11 | 0.1 |
| b1 | 2 | 20 | 22 | 0.1 |
| c1 | 3 | 30 | 33 | 0.1 |
| d1 | 4 | 40 | 44 | 0.1 |
| e1 | 5 | 50 | 55 | 0.1 |
内容的提问来源于stack exchange,提问作者roudan
相关产品推荐
相关产品推荐

