2016-05-29 8 views
1

У меня есть dataframe:Панды заменить полное слово строки

df = pd.DataFrame({'id' : ['abarth 1.4 a','abarth 1 a','land rover 1.3 r','land rover 2', 
          'land rover 5 g','mazda 4.55 bl'], 
        'series': ['a','a','r','','g', 'bl'] }) 

Я хотел бы, чтобы удалить строку в серии 'из соответствующего идентификатора, так что конечный результат должен быть:

'id': ['abarth 1.4','abarth 1','land rover 1.3','land rover 2','land rover 5', 'mazda 4.55']

В настоящее время я использую df.apply:

df.id = df.apply(lambda x: x['id'].replace(x['series'], ''), axis =1) 

Но это удаляет все экземпляры т он, например, так: 'id': ['brth 1.4','brth 1','land ove 1.3','land rover 2','land rover 5', 'mazda 4.55']

Должен ли я как-то смешивать и сопоставлять регулярное выражение с переменной внутри df.apply, так?

df.id = df.apply(lambda x: x['id'].replace(r'\b' + x['series'], ''), axis =1) 

ответ

1

Использование re, в случае, если вы хотите, чтобы указать series строку:

df.apply(lambda x: re.sub('\s*{}$'.format(x['series']), '', x['id']), axis=1) 

В случае series строка всегда предсказуемый шаблон (т.е. [a-z]), вы также можете попробовать:

df['id'].apply(lambda x: re.sub('\s*[a-z]+$', '', x)) 

В любом случае выход является тем, что вы ищете:

0  abarth 1.4 
1   abarth 1 
2 land rover 1.3 
3  land rover 2 
4  land rover 5 
5  mazda 4.55 
1

Вы можете использовать str.rpartition разделить id с на последнем пространстве.

In [169]: parts = df['id'].str.rpartition(' ')[[0,2]]; parts 
Out[169]: 
       0 2 
0  abarth 1.4 a 
1  abarth 1 a 
2 land rover 1.3 r 
3  land rover 2 
4 land rover 5 g 
5  mazda 4.55 bl 

Тогда вы могли бы использовать == для сравнения parts[2] к df['series']:

In [170]: mask = (parts[2] == df['series']); mask 
Out[170]: 
0  True 
1  True 
2  True 
3 False 
4  True 
5  True 
dtype: bool 

И, наконец, использовать df['id'].where заменить df['id] с parts[0] где mask это правда:

import pandas as pd 
df = pd.DataFrame(
    {'id' : ['abarth 1.4 a','abarth 1 a','land rover 1.3 r','land rover 2', 
      'land rover 5 g','mazda 4.55 bl'], 
    'series': ['a','a','r','','g', 'bl'] }) 
parts = df['id'].str.rpartition(' ')[[0,2]] 
mask = (parts[2] == df['series']) 
df['id'] = df['id'].where(~mask, parts[0], axis=0) 
print(df) 

дает

   id series 
0  abarth 1.4  a 
1  abarth 1  a 
2 land rover 1.3  r 
3 land rover 2  
4 land rover 5  g 
5  mazda 4.55  bl 

В качестве альтернативы, вы можете использовать

import re 
def remove_series(x): 
    pat = r'{}$'.format(x['series']) 
    return re.sub(pat, '', x['id']) 
df['id'] = df.apply(remove_series, axis=1) 

Но вызов df.apply с пользовательской функцией, как правило, гораздо медленнее, чем при использовании встроенных методов векторизации, таких как те, которые используются в первом способе.

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