Python 熊猫替换完整的字串

Python 熊猫替换完整的字串,python,pandas,Python,Pandas,我有一个数据帧: 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中删除“series”字符串,因此最终结

我有一个数据帧:

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中删除“series”字符串,因此最终结果应该是:

'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']

我是否应该以某种方式将regex与df.apply中的变量混合匹配,就像这样

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

您可以使用
str.rpartition
分割最后一个空格上的
id
s

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
然后您可以使用
==
部分[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']。其中
df['id
]替换为
部分[0]
,其中
掩码
为真:

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
往往比使用内置矢量化方法(如第一种方法中使用的方法)慢得多。

如果要指定
系列
字符串,请使用
re

df.apply(lambda x: re.sub('\s*{}$'.format(x['series']), '', x['id']), axis=1)
如果
系列
字符串始终是可预测的模式(即
[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