You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多列DataFrame中通过布尔索引为指定列赋值

问题

我有一个多级列DataFrame,索引为日期,第一级列是股票代码,第二级列是不同字段X1、X2、Y,数据结构如下:

df
   stock1                stock2                stock3       
   X1     X2     Y       X1     X2     Y       X1    X2     Y
0  True   False  NaN     False  False  NaN     True  False  NaN
1  False  True   NaN     True   False  NaN     True  False  NaN
3  False  False  NaN     True   False  NaN     False True   NaN
4  True   False  NaN     False  True   NaN     True  False  NaN

需求:利用X1和X2的布尔数组为Y赋值,规则是:

  • X1为True时,Y设为1
  • X2为True时,Y设为-1
  • 两者都为False时,保留Y的原有NaN值

我尝试用pd.IndexSlice获取X1和X2的视图,df.loc[:, idx[:, 'X1']]能返回正确的布尔数组,但赋值时遇到问题。比如用以下代码:

df.loc[:, idx[:, 'Y']] = (df.loc[:, idx[:, 'X1']] * 1).values

无法满足需求,因为False值会把Y设为0,而我需要保留NaN。

解决方案

方法1:嵌套np.where精准匹配条件

通过两层np.where依次判断X1、X2的布尔值,最后返回NaN满足“都为False时保留空值”的要求:

import numpy as np
import pandas as pd
idx = pd.IndexSlice

# 提取X1和X2的布尔矩阵
x1_mask = df.loc[:, idx[:, 'X1']]
x2_mask = df.loc[:, idx[:, 'X2']]

# 为Y列赋值
df.loc[:, idx[:, 'Y']] = np.where(x1_mask, 1, np.where(x2_mask, -1, np.nan))

方法2:先计算基础值再替换0为NaN

利用布尔值转整数的特性,先算出1/-1/0的结果,再把0替换成NaN:

idx = pd.IndexSlice

# X1转1/0,X2转1/0后取负,相加得到1/-1/0的矩阵
y_values = df.loc[:, idx[:, 'X1']].astype(int) - df.loc[:, idx[:, 'X2']].astype(int)
# 将0替换为NaN,匹配需求
y_values = y_values.replace(0, np.nan)
# 赋值给Y列
df.loc[:, idx[:, 'Y']] = y_values.values

方法3:拆解多级列简化操作

如果对多级列操作不熟悉,可以先将二级列转为行索引,处理后再恢复原结构:

# 把股票代码(第一级列)转成行索引
df_unstacked = df.unstack(level=0)
# 直接对每行的X1/X2判断赋值Y
df_unstacked['Y'] = np.where(df_unstacked['X1'], 1, np.where(df_unstacked['X2'], -1, np.nan))
# 恢复原多级列结构
df = df_unstacked.stack(level=0).swaplevel(0, 1, axis=1).sort_index(axis=1)

内容的提问来源于stack exchange,提问作者Vekkt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 00:06:22