首页 > 解决方案 > 在数据框中搜索字符串并将找到的数字增加 1

问题描述

我有一个手动创建的数据框。我正在编写一个复制数据帧并将新数据帧连接到第一个数据帧末尾的代码。现在,我需要代码来查看包含字符串的“名称”数据框的列的每个值,如果字符串中有数字,则将该数字增加 1。我需要将数字转换为 int这样我就可以创建一个函数来查看数据帧并自动将数据帧中的最大数字加 1。一个例子:

import pandas as pd
data = {'ID': [1,2,3,4],
        'Name': ['BN #1', 'HHC', 'A comp', 'B Comp']}
df = pd.DataFrame(data)

df['SysNum'] = [int(re.search('(?<=#)\d', x)[0]) for x in df['Name'].values]

之后新的df看起来像

data2 = {'ID': [1,2,3,4,5,6,7,8],
        'Name': ['BN #1', 'HHC', 'A comp', 'B Comp','BN #2', 'HHC', 'A comp', 'B Comp']} 

当我运行它时,我收到一个“NoneType”对象不可下标错误。这是有道理的,因为只有 BN # 行有一个数字,当不满足字符串参数时 re.search 返回 None ,但我不知道如何告诉 python 忽略其他行。

编辑每个数据帧只有第一行会增加 1,所以如果有一种更简单的方法我不使用 re.search,那很好。我知道有几种方法可以做到这一点,但我希望能够始终查看 BN 的字符串值,并在每次运行代码时将其增加 1。

正则表达式编辑

    df2['BaseName'] = [re.sub('\d', '', x) for x in df2['Name'].values]
    df['BaseName'] = [re.sub('\d', '', x) for x in df['Name'].values]
    df2['SysNum'] = [int(re.search('(?<=#)\d', x)[0]) for x in df2['Name'].values]
    # df2['SysNum'] = df2['Name'].get(r'(?<=#)\d').astype(int)
    # df['SysNum'] = [int(re.search('(?<=#)\d', x)[0]) for x in df['Name'].values]
    df['SysNum'] = df['Name'].str.contains('(?<=#)\d').astype(int)
    
    m =  re.search(r'(?<=#)\d', df2['Name'].iloc[0])
    if m:
        df2['SysNum'] = int(m.group(0)) + 1
    
    n = re.search(r'(?<=#)\d', df['Name'].iloc[0])
    if n:
        df['SysNum'] = int(n.group(1)) + 1
    
    
    new_names = df2['BaseName'].unique()
    maxes2 = np.zeros((len(new_names), ))
    
    for j in range(len(new_names)):
        un2 = new_names[j]
        maxes2[j] = df['SysNum'].loc[df['BaseName'] == un2].max()
        df2['SysNum'].loc[df2['BaseName'] == un2] = np.linspace(1, len(df2['SysNum'].loc[df2['BaseName'] == un2]), len(df2['SysNum'].loc[df2['BaseName'] == un2]))
        df2['SysNum'].loc[df2['BaseName'] == un2] += maxes2[j]
        newnames2 = [s + '%d' % num for s,num in zip(df2['BaseName'].loc[df2['BaseName'] == un2].values, df2['SysNum'].loc[df2['BaseName'] == un2].values)]
        df2['Name'].loc[df2['BaseName'] == un2] = newnames2

我有这个代码适用于两个数据框,编号可以按照我的意愿进行。前两个对数据框中的所有行都有一个“Name-###”命名约定。这允许顶部注释掉的 re.search 行运行得很好。我正在处理的接下来的两个数据框就像我之前用 BN #1 提出的示例,其余名称没有数字。当我运行注释掉的 re.search 行时,代码尝试将 NoneTypes 转换为 int 并且它不能这样做。当我现在按原样运行代码时,紧跟名称的每一行都会放置一个新数字,但我需要它在带有 # 的行中添加一个新数字。所以我需要并且我正在努力的是一段代码,它查看数据框,寻找 # 符号,将 # 符号后面的数字转换为 int,

标签: pythonregexre

解决方案


Name您可以使用 访问列第一行的值df['Name'].iloc[0]

#因此,您可以在使用该值登录后搜索一系列数字

m =  re.search(r'#(\d+)', df['Name'].iloc[0])
if m:
    df['SysNum'] = int(m.group(1)) + 1

输出:

>>> df
   ID    Name  SysNum
0   1   BN #1       2
1   2     HHC       2
2   3  A comp       2
3   4  B Comp       2

推荐阅读