Pandas为MultiIndex二级层级赋值时出现NaN问题
问题根因
赋值出现全NaN的核心是Pandas的索引对齐机制:
- 你通过
df_test.loc[('even',),1]选中的目标区域,行索引是MultiIndex中parity='even'对应的第二层mod5索引,标签为[0,1,2,3,4] - 你传入的赋值对象是
pd.DataFrame(np.arange(5)+5,index = np.arange(5)),是二维结构,且自身行索引没有和原表的mod5层级做匹配,Pandas对齐时找不到匹配的标签,就会全部填充为NaN - 你之前尝试的
df_test.loc['even']['1']属于链式索引,Pandas会先返回切片的副本而非原表视图,对副本的修改不会写入原DataFrame,这是官方明确不推荐的写法。
可行修正方案
以下任意一种写法都能得到预期结果:
方案1:直接传入一维数组赋值(最简洁)
不需要额外构造DataFrame,直接传入和目标切片长度一致的一维值序列即可,Pandas会按顺序赋值:
import pandas as pd import numpy as np df_test = pd.DataFrame( np.ones((10,2)), index = pd.MultiIndex.from_product( [['even','odd'],[0,1,2,3,4]], names = ['parity','mod5'] ) ) df_test.loc[('even',), 1] = np.arange(5) + 5
方案2:传入索引完全匹配的Series
如果需要用Pandas对象赋值,构造和目标区域第二层索引完全一致的一维Series,保证标签对齐:
assign_values = pd.Series( np.arange(5)+5, index=pd.Index([0,1,2,3,4], name='mod5') ) df_test.loc[('even',), 1] = assign_values
方案3:用IndexSlice明确切片范围(多层索引场景推荐)
多层索引切片时用pd.IndexSlice可以避免索引歧义,可读性更强:
idx = pd.IndexSlice df_test.loc[idx['even', :], 1] = np.arange(5) + 5
预期运行结果
执行上述任意一种修正代码后,输出如下:
0 1 parity mod5 even 0 1.0 5.0 1 1.0 6.0 2 1.0 7.0 3 1.0 8.0 4 1.0 9.0 odd 0 1.0 1.0 1 1.0 1.0 2 1.0 1.0 3 1.0 1.0 4 1.0 1.0
内容的提问来源于stack exchange,提问作者lag
相关产品推荐
相关产品推荐

