Pandas对比两DataFrame列值按规则生成二值矩阵实现方法
双DataFrame规则二值矩阵生成方案
需求概述
基于两个同结构、存储不同维度数据的DataFrame,按给定规则生成同形状的二值结果矩阵。
输入数据
两个测试DataFrame定义如下:
import pandas as pd import numpy as np market_values = pd.DataFrame({ 'variableA': (1,2.0,3), 'variableB': (np.nan,2,np.nan), 'variableC': (9,10,15), 'variableD' : (18,25,43), 'variableE':(36,11,12), 'variableF':(99,10,98), 'variableG': (42,19,27) }) negociation_values = pd.DataFrame({ 'variableA': (0.1,0.2,0.3), 'variableB': (0.5,np.nan,0.303), 'variableC': (0.9,0.10,0.4), 'variableD' : (0.12,0.11,0.09), 'variableE':(np.nan,0.13,0.21), 'variableF':(1.4,np.nan,0.03), 'variableG': (0.141,0.134,0.111) })
注:原提问中代码定义与打印输出存在笔误,已修正为和目标输出匹配的取值
处理规则
严格按4步执行:
- 检查
market_values中任意两列是否存在同一行索引下取值相等的情况 - 对满足同行等值条件的列对,提取
negociation_values中对应的同名列对 - 逐行对比提取的列对在
negociation_values中的取值大小 - 生成二值矩阵:
- 等值列对中,谈判值更高的变量对应行位置填1,更低的填0;若其中一列为空值(NaN),非空列填1,空值列填0
- 无任何匹配等值列的字段,整列所有位置填1
目标输出格式:
| variableA | variableB | variableC | variableD | variableE | variableF | variableG | |
|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
| 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
| 2 | 0 | 1 | 1 | 1 | 1 | 0 | 1 |
已实现逻辑
目前已完成前两步等值列对筛选,可正确得到存在同行等值的列对为[['variableA', 'variableB'], ['variableC', 'variableF']],已有代码如下:
arr = market_values.to_numpy() is_equal = ((arr == arr[None].T).any(axis=1)) is_equal[np.tril_indices_from(is_equal)] = False inds_of_same_cols = [*zip(*np.where(is_equal))] equal_cols = [market_values.columns[list(inds)].tolist() for inds in inds_of_same_cols]
后续步骤实现
直接初始化全1的结果矩阵,再遍历等值列对逐行覆盖赋值即可,完整可运行代码:
# 初始化结果矩阵,默认所有位置为1(匹配无等值列的赋值规则) result = pd.DataFrame(1, index=market_values.index, columns=market_values.columns) for col1, col2 in equal_cols: v1 = negociation_values[col1] v2 = negociation_values[col2] # 处理单值为空的情况 mask_v1_valid = v1.notna() & v2.isna() result.loc[mask_v1_valid, [col1, col2]] = [1, 0] mask_v2_valid = v2.notna() & v1.isna() result.loc[mask_v2_valid, [col1, col2]] = [0, 1] # 处理两值都存在的情况,按大小赋值 mask_v1_gt = v1 > v2 result.loc[mask_v1_gt, [col1, col2]] = [1, 0] mask_v2_gt = v2 > v1 result.loc[mask_v2_gt, [col1, col2]] = [0, 1] print(result)
运行后输出结果与目标格式完全一致。
内容的提问来源于stack exchange,提问作者Vinícius Felizatti
相关产品推荐
相关产品推荐

