如何用含行列索引的DataFrame为MultiIndex的DataFrame赋值
这是个很典型的MultiIndex定位赋值问题,我来帮你搞定!
问题的核心是要把index_array里的每一行转换成行MultiIndex元组和列MultiIndex元组,然后精准定位到to_fill的对应位置赋值为True。下面给你两种实用的解决方案:
方法1:直观循环(小数据友好)
直接遍历index_array的每一行,把每行的前两列、后两列分别打包成元组,作为loc的索引参数即可:
import numpy as np import pandas as pd lengths = pd.Series(data=[2, 4], index=[1, 2]) index = pd.MultiIndex.from_tuples([(i, j) for i in lengths.index for j in np.arange(1, lengths.loc[i]+1)]) to_fill = pd.DataFrame(index=index, columns=index, dtype=np.bool) to_fill.loc[:,:] = False # 用False更符合布尔类型的语义,替代你之前的0 index_array = pd.DataFrame([[1, 1, 1, 1], [1, 1, 1, 2], [2, 3, 2, 3], [2, 3, 2, 4]], columns=["i_1", "j_1", "i_2", "j_2"]) # 遍历每一行粒子对信息,精准赋值 for _, row in index_array.iterrows(): row_idx = (row["i_1"], row["j_1"]) col_idx = (row["i_2"], row["j_2"]) to_fill.loc[row_idx, col_idx] = True print(to_fill)
运行后就能得到你预期的结果,每一行index_array对应的位置都会被设为True。
方法2:批量索引赋值(大数据高效)
如果你的粒子对数量很大,循环的效率会比较低。这时候可以用get_indexer获取行和列的位置索引,直接操作底层values数组,速度会快很多:
import numpy as np import pandas as pd lengths = pd.Series(data=[2, 4], index=[1, 2]) index = pd.MultiIndex.from_tuples([(i, j) for i in lengths.index for j in np.arange(1, lengths.loc[i]+1)]) to_fill = pd.DataFrame(index=index, columns=index, dtype=np.bool) to_fill.loc[:,:] = False index_array = pd.DataFrame([[1, 1, 1, 1], [1, 1, 1, 2], [2, 3, 2, 3], [2, 3, 2, 4]], columns=["i_1", "j_1", "i_2", "j_2"]) # 把index_array的列转换成MultiIndex格式的元组集合 row_tuples = pd.MultiIndex.from_frame(index_array[["i_1", "j_1"]]) col_tuples = pd.MultiIndex.from_frame(index_array[["i_2", "j_2"]]) # 获取每个元组在to_fill索引中的位置下标 row_positions = to_fill.index.get_indexer(row_tuples) col_positions = to_fill.columns.get_indexer(col_tuples) # 批量赋值True to_fill.values[row_positions, col_positions] = True print(to_fill)
为什么你之前的尝试可能失败?
你大概率是直接用index_array的单列值去索引,但loc对于MultiIndex需要的是元组形式的完整标签,单独的列值只能匹配一级索引,无法定位到二级的j_1和j_2,所以必须把两级索引打包成元组才能正确命中目标位置。
内容的提问来源于stack exchange,提问作者jotasi
相关产品推荐
相关产品推荐

