为了账号安全,请及时绑定邮箱和手机立即绑定

替换数据框列中的多个字符串的函数 - “TypeError:预期的字符串或类似字节的对象”

替换数据框列中的多个字符串的函数 - “TypeError:预期的字符串或类似字节的对象”

喵喵时光机 2023-06-20 13:25:50
我有以下形式的大型数据框:FundManager | AsOfDate | InvestmentDesc | Amount  ManagerA | 6/1/2020 | Four Seasons 1st lien TL | 25500.86  ManagerA | 6/1/2020 | Arden Group First Lien TL | 28731.00  ManagerB | 6/1/2020 | Four Seasons 1L Term Loan | 16853.00  ManagerB | 6/1/2020 | Arden 1st Lien Term Loan | 50254.30相同的基础金融工具通常由多个资产管理人持有,但描述方式略有不同,如上表所示(例如“四季 1st 留置权 TL”与“四季 1L 定期贷款”)。我正在尝试找出对 pandas 数据框中的“InvestmentDesc”列进行某些替换的最佳方法(例如,将“Term Loan”替换为“TL”,将“1st Lien”替换为“1L”),理想情况下(i)以一种不必为每个术语重复遍历数百万行的方式,以及 (ii) 可以在数据框中的少数其他列上使用但使用单独的术语列表进行替换的方式。我目前有以下功能:def replace_all(dictReplace, text):    rep = dict((re.escape(k), v) for k, v in dictReplace.items())    pattern = re.compile("|".join(rep.keys()))    text = pattern.sub(lambda m: rep[re.escape(m.group(0))], text)    return text然后我试图将要替换的术语列表传递到其中(我假设是字典?)和要修改的现有数据框列:dictRepStrings = {"1st lien": "1l", "first lien": "1l", "2nd lien": "2l", "second lien": "2l", "term loan": "tl"}df['NewCol'] = df['InvestmentDesc'].apply(lambda x: replace_all(dictRepStrings, df['InvestmentDesc']))df然而,在这样做时,我最终得到“TypeError: expected string or bytes-like object”,如下所示:---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-10-a37630bdc5a4> in <module>     23      24 dictRepStrings = {"1st lien": "1l", "first lien": "1l", "2nd lien": "2l", "second lien": "2l", "term loan": "tl"}---> 25 df['NewCol'] = df['InvestmentDesc'].apply(lambda x: replace_all(dictRepStrings, df['InvestmentDesc']))     26 df~\anaconda3\lib\site-packages\pandas\core\series.py in apply(self, func, convert_dtype, args, **kwds)   3846             else:   3847                 values = self.astype(object).values-> 3848                 mapped = lib.map_infer(values, f, convert=convert_dtype)   3849    3850         if len(mapped) and isinstance(mapped[0], Series):经过两天的谷歌搜索直到沮丧,我根本无法弄清楚我做错了什么或如何解决。任何关于我应该如何进行的建议或想法将不胜感激!
查看完整描述

3 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

如果您有大型数据集,我会尝试使用numpy.selectand pandas.str.contains

import numpy as np

import pandas as pd



df["NewCol"] = np.select(

    condlist=[

        df["InvestmentDesc"].str.contains("1st lien|first lien", case=False, na=False),

        df["InvestmentDesc"].str.contains("2nd lien|second lien", case=False, na=False),

        df["InvestmentDesc"].str.contains("term loan", case=False, na=False),

    ],

    choicelist=[

        "1l", "2l", "tl"

    ],

    default=df["InvestmentDesc"]

)


查看完整回答
反对 回复 2023-06-20
?
郎朗坤

TA贡献1921条经验 获得超9个赞

您的应用函数存在语法问题。您不是将单个文本和字典作为参数传递,而是InvestmentDesc在应用程序中传递整个系列 ( ) 列。因此,该函数在使用 的调用期间失败lambda

  • 必需的:replace_all(dictReplace, text)

  • 鉴于:replace_all(dictRepStrings, df['InvestmentDesc'])

您可以自己解决这个问题,但为了可读性,我建议您进行一些小的更改。尝试将其与args参数一起使用。

def replace_all(text, dictReplace): #Made dictReplace as second parameter

    rep = dict((re.escape(k), v) for k, v in dictReplace.items())

    pattern = re.compile("|".join(rep.keys()))

    text = pattern.sub(lambda m: rep[re.escape(m.group(0))], text) 

    return text


dictRepStrings = {"1st lien": "1l", "first lien": "1l", "2nd lien": "2l", "second lien": "2l", "term loan": "tl"}

df['NewCol'] = df['InvestmentDesc'].apply(replace_all, args=[dictRepStrings]) #modified apply function with args

df

请注意,我通过删除更改了应用函数的结构lambda,添加了args参数并将其作为dict函数中的第二个参数,因此apply将每一行作为dict第一个参数传递,第二个参数定义在args


这对我有用,如果您仍然遇到问题,请告诉我。


查看完整回答
反对 回复 2023-06-20
?
杨魅力

TA贡献1811条经验 获得超6个赞

你也可以像这样做一些相对简单的事情:


def replacer(desc, replacers):

    for key in replacers.keys():

        if key in desc.lower():

            desc = desc.lower().replace(key, replacers[key]).title()

    return desc


replacers = {'1st lien': '1l', 'first lien': '1l', '2nd lien': '2l', 'second lien': '2l', 'term loan': 'tl'}


df['InvestmentDesc'].apply(replacer, replacers=replacers)

输出:


0    Four Seasons 1L Tl

1     Arden Group 1L Tl

2    Four Seasons 1L Tl

3           Arden 1L Tl

不确定大写是否重要,或者你可以稍微调整一下以获得你想要的大写。但我认为这是一个非常简单的解决方案,并且还将考虑每个字符串中的多个匹配项


也许可以针对不区分大小写的正则表达式搜索/替换修改它,但原理相同


查看完整回答
反对 回复 2023-06-20
  • 3 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信