Pandas str.extract:AttributeError:' str'对象没有属性' str'

时间:2015-06-25 09:15:39

标签: python regex python-2.7 pandas

我试图将此功能重新用于使用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直接使用字符串?

1 个答案:

答案 0 :(得分: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