【问题标题】:Pandas str.extract: AttributeError: 'str' object has no attribute 'str'Pandas str.extract:AttributeError:'str'对象没有属性'str'
【发布时间】:2015-09-11 19:21:54
【问题描述】:

我正在尝试将此函数的用途从使用 split 改为使用 str.extract(正则表达式)。

def bull_lev(x):
    spl = x.rsplit(None, 2)[-2].strip("Xx")
    if spl.str.isdigit():
        return "+" + spl + "00"
    return "+100"

def bear_lev(x):
    spl = x.rsplit(None, 2)[-2].strip("Xx")
    if spl.str.isdigit(): 
        return "-" + spl + "00"
    return "-100"

df["leverage"] = df["name"].map(lambda x: bull_lev(x)
    if "BULL" in x else bear_lev(x) if "BEAR" in x else "+100"

我正在使用pandas 处理DataFrame

import pandas as pd
df = pd.DataFrame(["BULL AXP UN X3 VON", "BEAR ESTOX 12x S"], columns=["name"])

期望的输出:

name                    leverage
"BULL AXP UN X3 VON"    "+300"
"BEAR ESTOX 12x S"      "-1200"

"BULL" 的正则表达式尝试错误:

def bull_lev(x):
    #spl = x.rsplit(None, 2)[-2].strip("Xx")
    spl = x.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).strip("x")
    if spl.str.isdigit():
        return "+" + spl + "00"
    return "+100"

df["leverage"] = df["name"].map(lambda x: bull_lev(x)
    if "BULL" in x else bear_lev(x) if "BEAR" in x else "+100")

产生错误:

Traceback (most recent call last):
  File "toolkit.py", line 128, in <module>
    df["leverage"] = df["name"].map(lambda x: bull_lev(x)
  File "/Python/Virtual/py2710/lib/python2.7/site-packages/pandas/core/series.py", line 2016, in map
    mapped = map_f(values, arg)
  File "pandas/src/inference.pyx", line 1061, in pandas.lib.map_infer (pandas/lib.c:58435)
  File "toolkit.py", line 129, in <lambda>
    if "BULL" in x else bear_lev(x) if "BEAR" in x else "+100")
  File "toolkit.py", line 123, in bear_lev
    spl = x.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).strip("x")

AttributeError: 'str' object has no attribute 'str'

我假设这是由于str.extract 捕获列表而split 直接使用字符串?

【问题讨论】:

    标签: python regex python-2.7 pandas


    【解决方案1】:

    您可以使用以下方法处理肯定的情况:

    In [150]:
    import re
    df['fundleverage'] = '+' + df['name'].str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X') + '00'
    df
    
    Out[150]:
                     name fundleverage
    0  BULL AXP UN X3 VON         +300
    1    BULL ESTOX X12 S        +1200
    

    您可以使用np.where 来同时处理这两种情况:

    In [151]:
    df['fundleverage'] = np.where(df['name'].str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X').str.isdigit(),  '+' + df['name'].str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X') + '00', '+100')
    df
    
    Out[151]:
                     name fundleverage
    0  BULL AXP UN X3 VON         +300
    1    BULL ESTOX X12 S        +1200
    

    所以上面使用了向量化的str方法stripextractisdigit来实现你想要的。

    更新

    在您更改要求后(您不应该这样做以供将来参考),您可以为牛市和熊市情况掩盖 df:

    In [189]:
    import re
    df = pd.DataFrame(["BULL AXP UN X3 VON", "BEAR ESTOX 12x S"], columns=["name"])
    bull_mask_name = df.loc[df['name'].str.contains('bull', case=False), 'name']
    bear_mask_name = df.loc[df['name'].str.contains('bear', case=False), 'name']
    df.loc[df['name'].str.contains('bull', case=False), 'fundleverage'] = np.where(bull_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X').str.isdigit(),  '+' + bull_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X') + '00', '+100')
    df.loc[df['name'].str.contains('bear', case=False), 'fundleverage'] = np.where(bear_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('x').str.isdigit(),  '-' + bear_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('x') + '00', '-100')
    df
    
    Out[189]:
                     name fundleverage
    0  BULL AXP UN X3 VON         +300
    1    BEAR ESTOX 12x S        -1200
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 2019-03-25
      • 2017-05-13
      • 2014-04-28
      相关资源
      最近更新 更多