如果条件不满足,为什么np.where在有条件的情况下不能只处理数据帧中的一行

2024-09-26 22:50:48 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是一个例子:

cars2 = {'Brand': ['Hon*da\nCivic', 'BM*AMT*B6*W'],'Price': [22000, 55000]}

df2 = pd.DataFrame(cars2, columns = ['Brand', 'Price'])


df2['Allowed_Amount'] = np.where(
                df2['Brand'].apply(lambda x: x.count("AMT" + "*" + "B6") > 0),
                df2['Brand'].str.split("AMT" + "*").str[1].str.split("B6").str[1].str[1:].str.split('\n').str[0], 0.00)

输出:

           Brand  Price Allowed_Amount
0  Hon*da\nCivic  22000              0
1    BM*AMT*B6*W  55000              W

这正是我需要的

但是,如果df只包含一行,这不满足条件,则我会得到一个错误:

cars = {'Brand': ['Hon*da\nCivic'],'Price': [22000]}

df = pd.DataFrame(cars, columns = ['Brand', 'Price'])

df['Allowed_Amount'] = np.where(
                    df['Brand'].apply(lambda x: x.count("AMT" + "*" + "B6") > 0),
                    df['Brand'].str.split("AMT" + "*").str[1].str.split("B6").str[1].str[1:].str.split('\n').str[0], 0.00)

输出:

AttributeError: Can only use .str accessor with string values!

我需要的是:

           Brand  Price Allowed_Amount
0  Hon*da\nCivic  22000              0

为什么不在不满足条件时退出?如何使这段代码也适用于一行


Tags: dfamountpricedabmsplitdf2allowed
1条回答
网友
1楼 · 发布于 2024-09-26 22:50:48

代码中的问题是,df['Brand'].str.split(“AMT”+“”)*在 “negative”大小写返回一个大小为1的列表(在 单个元素)

在本例中,.str[1](在前面的代码之后)返回None和 无法对代码中的“以下”方法进行调用

但在Pandas中,仅当出现上述情况时,才会引发实际异常 对于每个源元素发生,就像df的情况一样

我还认为,str.splitstr和index 选集很难读

使用正则表达式尝试另一种基于提取的方法:

df['Allowed_Amount'] = df['Brand'].str.extract(r'AMT\*.*?B6.(.*)').fillna(0)

正则表达式的详细信息:

  • AMT\*-匹配{}和一个星号
  • .*?-匹配任意数量的字符,尽可能少(字符 在“金额*”和“B6”之间(如有)。也许你可以放下这个碎片 来自正则表达式
  • B6-代表他们自己
  • .-匹配任何单个字符(代码中[1:]的对应字符)
  • (.*)-将文本匹配到换行符(不包括,因为点不匹配 换行符)或字符串末尾,作为捕获组,因此 只是提取的内容

如果上述正则表达式不匹配,则为此行返回NaN

由于调用fillna(0) 后来

df2上尝试同样的方法

因此,通过这种方式,您可以使用更短、更可读的代码来实现所需的结果

当然,它需要一些关于正则表达式的知识,但它是 绝对值得花些时间来学习它们

编辑以下问题

要用给定的分隔符替换正则表达式中的文字星号, 您可以定义以下函数,生成内容 对于新列:

def myExtract(df, delimiter='*'):
    pat = rf'AMT\{delimiter}B6.(.*)'
    return df['Brand'].str.extract(pat).fillna(0)

如你所见:

  • 使用f-string分隔符合并到正则表达式中 功能(可以与r-string共存)
  • 它的前面必须加反斜杠,才能按字面意思处理 (不是作为特殊的正则表达式字符)

要生成新的列,只需调用此函数,在 至少源数据帧(以及可选的右分隔符):

df['Allowed_Amount'] = myExtract(df); df

对于df2也一样

相关问题 更多 >

    热门问题