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

如何基于另一DataFrame的条件为DataFrame应用style.applymap方法

解决DataFrame.style.applymap指定多位置上色的问题

我有两个尺寸相同的3×3 DataFrame:一个是布尔型(存储True/False),另一个是数值型。需求是允许用户输入布尔矩阵的坐标,将对应位置从False改为True(已为True则忽略操作),之后使用style.applymap函数为数值型DataFrame中与布尔矩阵True值对应的元素上色。但在使用subset参数时遇到困难,无法指定多个行索引,运行时出现KeyError: "None of [Index([(1, 2)], dtype='object')] are in the [index]"错误。

原始错误代码示例:

import pandas as pd
import numpy as np

Occupato = pd.DataFrame(np.zeros(shape = (3, 3)))
for i in range(3):
    Occupato = Occupato.astype({i: bool})

normale = pd.DataFrame(np.random.randint(0,10,size=(3, 3)), columns=list('ABC')) 

def colore(v, colore):
    return f"background-color: {colore};" 

idx = ('Insert coordinates as [x, y]: ')
Occupato.iloc[idx[0], idx[1]]
normale.style.applymap(colore, colore='blue', subset = (row), [columns])

方案一:在样式函数中直接结合布尔矩阵判断(推荐)

这种方式不需要复杂的subset构造,直接在样式函数内检查当前元素的位置是否在布尔矩阵中为True,逻辑更直观:

import pandas as pd
import numpy as np

# 初始化布尔型DataFrame(直接指定dtype=bool更简洁)
Occupato = pd.DataFrame(np.zeros((3, 3), dtype=bool), columns=list('ABC'))
# 初始化数值型DataFrame
normale = pd.DataFrame(np.random.randint(0, 10, size=(3, 3)), columns=list('ABC')) 

def colore(val, bool_df):
    # 获取当前元素的行、列索引
    row_idx, col_idx = val.name[0], val.name[1]
    # 检查对应布尔矩阵位置是否为True
    if bool_df.iloc[row_idx, col_idx]:
        return "background-color: blue;"
    # 不需要上色则返回空字符串
    return ""

# 获取用户输入并更新布尔矩阵
coord_input = input("Insert coordinates as x,y: ")
x, y = map(int, coord_input.split(','))
# 仅当当前为False时更新(避免重复操作)
if not Occupato.iloc[x, y]:
    Occupato.iloc[x, y] = True

# 应用样式,将布尔矩阵传递给样式函数
styled_result = normale.style.applymap(colore, bool_df=Occupato)
# 展示结果
styled_result

方案二:正确构造subset参数指定目标位置

如果一定要通过subset参数限定上色范围,需要将布尔矩阵中所有True的位置转换成行索引数组和列索引数组的组合,注意这里的行和列是一一对应的,而非笛卡尔积:

import pandas as pd
import numpy as np

Occupato = pd.DataFrame(np.zeros((3, 3), dtype=bool), columns=list('ABC'))
normale = pd.DataFrame(np.random.randint(0, 10, size=(3, 3)), columns=list('ABC')) 

def colore(v):
    return "background-color: blue;"

# 获取用户输入并更新布尔矩阵
coord_input = input("Insert coordinates as x,y: ")
x, y = map(int, coord_input.split(','))
if not Occupato.iloc[x, y]:
    Occupato.iloc[x, y] = True

# 收集布尔矩阵中所有True的位置
true_rows, true_cols = np.where(Occupato)
# 将列索引转换为对应的列名(因为normale的列是'A'/'B'/'C')
target_cols = normale.columns[true_cols]

# 正确构造subset:(行索引列表, 列名列表)
styled_result = normale.style.applymap(colore, subset=(true_rows, target_cols))
styled_result

错误原因解析

之前的代码存在两个核心问题:

  1. 坐标输入处理错误:仅定义了字符串提示,未通过input()获取用户输入并转换为整数索引;
  2. subset参数使用错误:
    • 语法错误:subset = (row), [columns]不符合Python语法,正确格式应为subset=(行选择器, 列选择器);
    • 索引理解错误:若传递(1,2)作为行选择器,会被当成单个索引值而非行1和行2,需用数组/列表形式传递多个行索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:47:43