[英]Pandas replace full word string
我有一個數據框:
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中刪除“系列”字符串,因此最終結果應為:
'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
。
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
將mask
為True的parts[0]
替換df['id
]:
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
往往比使用內置的矢量化方法(例如第一種方法中使用的方法)要慢得多。
如果要指定series
字符串,請使用re
:
df.apply(lambda x: re.sub('\s*{}$'.format(x['series']), '', x['id']), axis=1)
如果series
字符串始終是可預測的模式(即[az]
),您也可以嘗試:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.