2015-06-25 4 views
1

Я пытаюсь перепрофилировать эту функцию с помощью вместо str.extract (regex).Pandas str.extract: AttributeError: объект 'str' не имеет атрибута 'str'

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 работ непосредственно со строкой?

ответ

0

Вы можете обрабатывать положительный случай, используя следующее:

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 

Так выше использует vectorised str методы strip , extract и isdigit для достижения того, чего вы хотите.

Update

После того, как вы изменили свои требования (которые вы не должны делать для дальнейшего использования), вы можете маскировать ФР для бычьих и медвежьих случаев:

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 
+0

Спасибо за это. Хотя решение кажется очень практичным, я немного борюсь с этим, так как мне также нужно определить «случай» для «BEAR», где множитель отрицательный: '-300' и' -1200'. Возможно, я ошибаюсь в «np.where», но я попытался определить, что он ищет '.str.extract (r" (BEAR \ s. +) 'И использовать это как селектор для отрицательного случая' '-' + ' df ['name]' '... Не работает, однако. – Winterflags

+0

Вы можете либо вложить другое' where', либо замаскировать df для отрицательного случая, но на самом деле вам нужно объявить, что вы хотите, или отправить другой вопрос, увеличивая ваши требования не является хорошей практикой – EdChum

+0

Я согласен, я ограничил вопрос слишком далеко для краткости. Я ожидал функцию, которую я мог бы просто инвертировать. – Winterflags

Смежные вопросы