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

Python 如果条件不满足,为什么np.where在有条件的情况下不能只处理数据帧中的一行,python,pandas,numpy,parsing,split,Python,Pandas,Numpy,Parsing,Split,以下是一个例子: 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")

以下是一个例子:

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
AttributeError: Can only use .str accessor with string values!
这正是我需要的

但是,如果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)
输出:

           Brand  Price Allowed_Amount
0  Hon*da\nCivic  22000              0
1    BM*AMT*B6*W  55000              W
AttributeError: Can only use .str accessor with string values!
我需要的是:

           Brand  Price Allowed_Amount
0  Hon*da\nCivic  22000              0

为什么不在不满足条件时退出?如何使此代码也能处理一行?

代码的问题在于 “negative”大小写返回一个大小为1的列表(在 单个元素)

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

但在熊猫中,只有在上述情况下,才会引发实际异常 对于每个源元素发生,就像df的情况一样

我还认为str.split、str和index的长序列 选集很难读

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

df['Allowed_Amount'] = df['Brand'].str.extract(r'AMT\*.*?B6.(.*)').fillna(0)
正则表达式的详细信息:

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

由于调用fillna(0),这些NaN值随后被替换为0 后来

在df2上尝试同样的方法

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

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

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

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

  • 使用f字符串将分隔符合并到正则表达式中 特征(可以与r字符串共存)
  • 它的前面必须加反斜杠,才能按字面意思处理 (不是作为特殊的正则表达式字符)
要生成新的列,只需调用此函数,在 至少源数据帧(以及可选的右分隔符):


df2也是如此。

代码的问题在于 “negative”大小写返回一个大小为1的列表(在 单个元素)

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

但在熊猫中,只有在上述情况下,才会引发实际异常 对于每个源元素发生,就像df的情况一样

我还认为str.split、str和index的长序列 选集很难读

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

df['Allowed_Amount'] = df['Brand'].str.extract(r'AMT\*.*?B6.(.*)').fillna(0)
正则表达式的详细信息:

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

由于调用fillna(0),这些NaN值随后被替换为0 后来

在df2上尝试同样的方法

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

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

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

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

  • 使用f字符串将分隔符合并到正则表达式中 特征(可以与r字符串共存)
  • 它的前面必须加反斜杠,才能按字面意思处理 (不是作为特殊的正则表达式字符)
要生成新的列,只需调用此函数,在 至少源数据帧(以及可选的右分隔符):


df2也是一样。

IIUC您可以使用
df2['Allowed_Amount']=df2['Brand'].str.extract(r.'*AMT\*B6\*(.*)).fillna(0)
替代?IIUC您可以使用
df2['Allowed_Amount']=df2['Brand'].str.extract(r.'*AMT\*B6\*(.*)).fillna(0)
替代?您好,谢谢您的回答。我还有一个问题:在实际代码中,星号是一个分隔符,因此它会有所不同。在本例中,我将其作为分隔符=“*”。我怎样才能将其合并到您的代码中?我还可以编写另一个变量:my_string=“AMT”+delimiter+“B6”,但我如何将其放入您的代码中?您好,谢谢您的回答。我还有一个问题:在实际代码中,星号是一个分隔符,因此它会有所不同。在本例中,我将其作为分隔符=“*”。我怎样才能将其合并到您的代码中?我还可以编写另一个变量:my_string=“AMT”+delimiter+“B6”,但如何将其放入代码中?