R语言:基于同维度df2字符串筛选保留df1对应数值
问题描述
我有两个维度相同的DataFrame(df1与df2):
- df1为数值型数据:
df1 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 1 1 11 21 31 41 51 61 71 81 91 2 2 12 22 32 42 52 62 72 82 92 3 3 13 23 33 43 53 63 73 83 93 4 4 14 24 34 44 54 64 74 84 94 5 5 15 25 35 45 55 65 75 85 95 6 6 16 26 36 46 56 66 76 86 96 7 7 17 27 37 47 57 67 77 87 97 8 8 18 28 38 48 58 68 78 88 98 9 9 19 29 39 49 59 69 79 89 99 10 10 20 30 40 50 60 70 80 90 100
- df2为字符串型数据(部分单元格包含多个字符串,例如[1,V10]):
df2 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 1 today today today today yesterday today today today today tomorrow,today 2 today today today today today yesterday today today today today 3 today yesterday today today today today today yesterday today today 4 today today today today today today today today tomorrow,today today 5 today today today yesterday yesterday today today today today tomorrow 6 today today today yesterday today tomorrow,today today today today today 7 today today today today today yesterday today today today tomorrow,today 8 today yesterday today today today today today today today today 9 today today today today today today today today tomorrow,today today 10 today yesterday today yesterday today today today yesterday today today
df1与df2的单元格一一对应(如df1[1,1]对应df2[1,1])。需要无需使用for循环的简便方法,仅保留df1中对应df2单元格包含"today"的数值,其余设为NA。期望输出如下:
期望输出 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 1 1 11 21 31 NA 51 61 71 81 91 2 2 12 22 32 42 NA 62 72 82 92 3 3 NA 23 33 43 53 63 NA 83 93 4 4 14 24 34 44 54 64 74 84 94 5 5 15 25 NA NA 55 65 75 85 NA 6 6 16 26 NA 46 56 66 76 86 96 7 7 17 27 37 47 NA 67 77 87 97 8 8 NA 28 38 48 58 68 78 88 98 9 9 19 29 39 49 59 69 79 89 99 10 10 NA 30 NA 50 60 70 NA 90 100
解决方案
R语言实现
利用向量化操作结合grepl函数直接处理,全程无需循环:
# 生成逻辑矩阵,标记df2中包含"today"的单元格 today_mask <- grepl("today", df2) # 复制df1,将对应mask为FALSE的位置设为NA result_df <- df1 result_df[!today_mask] <- NA
也可以用一行代码简化:
result_df <- df1 * NA^!grepl("today", df2)
解释:grepl("today", df2)返回和df2维度一致的逻辑矩阵,!取反后,NA^逻辑值会把TRUE转为NA、FALSE转为1,和df1相乘后,对应位置为NA的会自动将df1的数值转为NA,完全符合需求。
Python(Pandas)实现
借助Pandas的向量化字符串方法生成布尔掩码,再通过where方法完成赋值:
import pandas as pd import numpy as np # 生成布尔掩码,na=False避免空值干扰判断 today_mask = df2.apply(lambda x: x.str.contains("today", na=False)) # 保留满足条件的数值,其余设为NaN result_df = df1.where(today_mask)
也可以分步写更直观:
result_df = df1.copy() result_df[~today_mask] = np.nan
解释:df.where()方法会保留满足条件的原数值,不满足的自动设为NaN;str.contains用于检查每个单元格是否包含"today",na=False确保空单元格被判定为不包含目标字符串。
内容的提问来源于stack exchange,提问作者user18632888
相关产品推荐
相关产品推荐

