无需迭代:按指定DataFrame条件匹配行列批量置零的实现方法
问题描述
现有两个Pandas DataFrame:
conditionDataFrame,数据结构如下:
0 [3, 4] 1 [2]
df2初始数据如下:
1 2 3 4 0 0.275464 0.275404 0.2782 0.273485 1 0.275464 0.275404 0.2782 0.273485
需求是将df2中对应位置设置为0:第0行的3、4列,第1行的2列,最终df2需变为:
1 2 3 4 0 0.275464 0.275404 0.0000 0.0000 1 0.275464 0.000000 0.2782 0.273485
询问是否存在无需遍历行的高效实现方式?
高效实现方案(无需显式遍历行)
当然有,以下两种基于Pandas矢量化操作的方法可以高效完成需求:
方法一:通过explode构造坐标掩码
先将condition中的列列表展开为行号-列号的配对,再构造布尔掩码批量赋值:
import pandas as pd # 构造示例数据 condition = pd.DataFrame({'cols': [[3,4], [2]]}) df2 = pd.DataFrame({ 1: [0.275464, 0.275464], 2: [0.275404, 0.275404], 3: [0.2782, 0.2782], 4: [0.273485, 0.273485] }) # 展开列列表并保留原行号 idx_col_pairs = condition.explode('cols').reset_index() # 初始化全False的掩码矩阵 mask = pd.DataFrame(False, index=df2.index, columns=df2.columns) # 将需要置0的位置标记为True mask.loc[idx_col_pairs['index'], idx_col_pairs['cols']] = True # 批量赋值为0 df2[mask] = 0
方法二:利用apply生成行级掩码
通过apply为每行生成对应需要置0的列的掩码,再用mask方法批量替换:
import pandas as pd # 构造示例数据 condition = pd.DataFrame({'cols': [[3,4], [2]]}) df2 = pd.DataFrame({ 1: [0.275464, 0.275464], 2: [0.275404, 0.275404], 3: [0.2782, 0.2782], 4: [0.273485, 0.273485] }) # 为每行生成需要置0的列的布尔掩码 row_mask = condition['cols'].apply(lambda cols: df2.columns.isin(cols)) # 将掩码对应的位置替换为0 df2 = df2.mask(row_mask, 0)
这两种方法都利用了Pandas的矢量化运算特性,避免了显式的行遍历,在数据量较大时性能优势明显。
内容的提问来源于stack exchange,提问作者John Tan
相关产品推荐
相关产品推荐

