熊猫取代了完整的单词串

时间:2016-05-29 01:21:37

标签: 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'字符串,因此最终结果应为:

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

2 个答案:

答案 0 :(得分: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'].wheredf['id]替换为parts[0],其中mask为True:

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

答案 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