如何无需iteritems迭代,用布尔DataFrame为多层索引DataFrame赋值?
问题:无需迭代实现多层索引DataFrame的掩码赋值?
我有一个带MultiIndex(多层索引)的DataFrame df,以及一个无多层索引的布尔型DataFrame sdf,希望用sdf作为预筛选掩码为df赋值。当前用iteritems迭代实现了需求,想知道能不能不通过迭代完成?
原实现代码
import pandas as pd mi = pd.MultiIndex.from_product([['A', 'B'], [1, 2]]) df = pd.DataFrame([[0, 1, 2, 3], [1, 2, 3, 4]], columns=mi, index=[0, 1]) print(df) sdf = pd.DataFrame([[True, False], [False, True]], columns=['A', 'B']) print(sdf) for name, value in sdf.iteritems(): df.loc[value, name] = 10 print(df)
原代码输出
A B 1 2 1 2 0 0 1 2 3 1 1 2 3 4 A B 0 True False 1 False True A B 1 2 1 2 0 10 10 2 3 1 1 2 10 10
无需迭代的实现方法
可以利用Pandas的索引对齐特性,将sdf扩展为与df列结构完全匹配的布尔掩码,直接完成赋值操作,无需循环:
方法一:通过reindex对齐多层索引
利用reindex的level参数,将sdf的列按df的第一层索引对齐,自动扩展出对应第二层索引的列,生成与df形状一致的掩码:
import pandas as pd mi = pd.MultiIndex.from_product([['A', 'B'], [1, 2]]) df = pd.DataFrame([[0, 1, 2, 3], [1, 2, 3, 4]], columns=mi, index=[0, 1]) sdf = pd.DataFrame([[True, False], [False, True]], columns=['A', 'B']) # 构造与df列结构匹配的布尔掩码 mask = sdf.reindex(df.columns, level=0, axis=1) # 赋值 df[mask] = 10 print(df)
方法二:通过广播扩展维度
将sdf的二维数组扩展为与df形状一致的三维数组,再重塑为二维掩码:
import pandas as pd mi = pd.MultiIndex.from_product([['A', 'B'], [1, 2]]) df = pd.DataFrame([[0, 1, 2, 3], [1, 2, 3, 4]], columns=mi, index=[0, 1]) sdf = pd.DataFrame([[True, False], [False, True]], columns=['A', 'B']) # 计算第二层索引的唯一值数量 level1_count = df.columns.get_level_values(1).nunique() # 广播扩展并重塑为与df匹配的形状 mask = sdf.values[:, :, None].repeat(level1_count, axis=2).reshape(df.shape) # 赋值 df[mask] = 10 print(df)
两种方法都能得到和原迭代代码完全一致的输出:
A B 1 2 1 2 0 10 10 2 3 1 1 2 10 10
内容的提问来源于stack exchange,提问作者Chachni
相关产品推荐
相关产品推荐

