Pandas从源DataFrame单列生成多列出现NaN值如何解决
问题根本原因
两种写法出现NaN的核心原因是:从原DataFrame中按颜色过滤得到的每个Height序列都保留了原表的行索引,不同颜色对应的行索引完全不重叠。pandas的列赋值、concat操作默认会按行索引对齐,索引匹配失败的位置会自动填充NaN,第二种concat写法甚至会把所有索引拼接在一起,才会出现72行大量空值的结果。
另外需要注意:如果你的原数据Color列的值为小写(比如示例数据里的red/orange),需要把过滤条件里的大写首字母改成和原数据一致,否则过滤不到数据也会得到全空结果。
修复方案
方案1:修改现有写法
对每个过滤出来的Height序列调用.reset_index(drop=True)丢弃原有索引,让所有序列的索引都变为从0开始的连续值,即可正常对齐:
第一种写法修改版
lastdate = '10/23/2021' column_names = ["Red", "Orange", "Yellow","Green","Blue","Indigo","Violet","Black","Brown"] dftcolorAgg = pd.DataFrame(columns = column_names) dftcolorAgg['Red'] = df[(df['Color'] == 'Red') & (df['Date'] == lastdate)].Height.reset_index(drop=True) dftcolorAgg['Orange'] = df[(df['Color'] == 'Orange') & (df['Date'] == lastdate)].Height.reset_index(drop=True) dftcolorAgg['Yellow'] = df[(df['Color'] == 'Yellow') & (df['Date'] == lastdate)].Height.reset_index(drop=True) # 剩余列按同样规则添加.reset_index(drop=True)即可
第二种写法修改版
red = df[(df['Color'] == 'Red') & (df['Date'] == lastdate)].Height.reset_index(drop=True) orange = df[(df['Color'] == 'Orange') & (df['Date'] == lastdate)].Height.reset_index(drop=True) yellow = df[(df['Color'] == 'Yellow') & (df['Date'] == lastdate)].Height.reset_index(drop=True) # 剩余颜色序列按同样规则添加.reset_index(drop=True)即可 dftcolorAgg = pd.concat([red, orange,yellow,green,blue,indigo,violet,black,brown], axis=1, keys=column_names)
方案2:透视表实现(更简洁,推荐)
不需要手动拆分每个颜色的列,直接用透视功能一步得到结果:
lastdate = '10/23/2021' # 先过滤出指定日期的数据 tmp_df = df[df['Date'] == lastdate].copy() # 给相同颜色的行生成分组内的连续序号作为行索引 tmp_df['idx'] = tmp_df.groupby('Color').cumcount() # 透视直接得到目标结构 dftcolorAgg = tmp_df.pivot(index='idx', columns='Color', values='Height').reset_index(drop=True)
内容的提问来源于stack exchange,提问作者Leo Torres
相关产品推荐
相关产品推荐

