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

在Pandas中实现字符串部分匹配并提取匹配值至新列的技术问询

解决DataFrame中按行匹配字符生成新列的问题

首先看你的需求:要把每行letter列的字符,和同一行其他列(info1-info4)的字符串开头匹配,把匹配到的内容放到new列,没匹配就填NaN。你的初始尝试用了isin和any,但这个方法是检查整个单元格的值是否在letter列的全局集合里,而我们需要的是单元格字符串的前缀是否等于当前行的letter值,所以这个思路不对。

下面给你两种可行的解决方案:

方法一:逐行遍历匹配(直观易懂)

我们可以用apply函数逐行处理,对每行来说,取出letter的值,然后遍历其他列的元素,找到以该letter开头的那个元素,找不到就返回NaN:

import pandas as pd

d = {'letter':['R','V','Q','M','F','K'], 'info1':['K:2.3','T:1.3','L:2.4','B:7.4','S:2.3','K:4.4'], 'info2':['R:3.2','N:2.1','B:0.3','T:0.9','J:0.003','S:1.223'], 'info3':['X:45','V:32.4','H:0.04','M:3.34','T:2.2','T:3.456'], 'info4':['A:1.7','Z:1.2345','T:9.5','O:3,2','J:3.334','G:345']}
df1 = pd.DataFrame(d)

def find_match(row):
    target = row['letter']
    # 遍历除了letter之外的列
    for col in ['info1', 'info2', 'info3', 'info4']:
        val = row[col]
        if val.startswith(target):
            return val
    return pd.NA  # 也可以用np.nan

df1['new'] = df1.apply(find_match, axis=1)

运行后就能得到你想要的结果:

letter   info1     info2     info3      info4      new
0      R  K:2.3    R:3.2      X:45     A:1.7    R:3.2
1      V  T:1.3    N:2.1    V:32.4  Z:1.2345  V:32.4
2      Q  L:2.4    B:0.3   H:0.04     T:9.5      NaN
3      M  B:7.4    T:0.9    M:3.34    O:3,2    M:3.34
4      F  S:2.3  J:0.003    T:2.2  J:3.334      NaN
5      K  K:4.4  S:1.223  T:3.456    G:345    K:4.4

方法二:向量化操作(更高效,适合大数据)

如果你的DataFrame行数很多,apply的效率可能不够,我们可以用向量化的方法,先对每个info列生成匹配掩码,然后提取对应的值:

# 提取所有info列
info_cols = [col for col in df1.columns if col.startswith('info')]

# 对每个info列,生成是否以当前行letter开头的布尔矩阵
matches = df1[info_cols].apply(lambda x: x.str.startswith(df1['letter'], na=False))

# 找到每行第一个匹配的列,提取对应的值
df1['new'] = df1[info_cols].where(matches).bfill(axis=1).iloc[:, 0]

这个方法的原理是:

  1. 先创建一个布尔矩阵,每个元素表示对应info列的单元格是否以该行的letter开头
  2. 用where把不匹配的位置变成NaN,然后用bfill(或ffill)把每行第一个匹配的值填充到第一列
  3. 最后提取第一列就是我们要的结果

为什么你的初始代码不行?

你原来的代码df1['new'] = df1.drop("letter", 1).isin(df1["letter"]).any(1)存在两个问题:

  • 它是检查每个单元格的值是否完全等于整个letter列的任意值,不是当前行的letter值
  • 最终返回的是每行是否有匹配的布尔值(True/False),而不是你需要的匹配字符串

这就是为什么这个方法达不到你想要的效果啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 22:57:45