我有以下代码片段:
import pandas as pd
df = pd.DataFrame([{'LastName':'VAN HOUTEN'},
{'LastName':"O'BOYLE"},
{'LastName':'ESTEVAN-GONZALEZ'},
{'LastName':'RODRIGO TEIXEIRA'},
{'LastName':'ESTEBAN GONZALEZ'},
{'LastName':'O ROURKE'},
{'LastName':'RODRIGO-TEIXEIRA'}])
delete_space_after_list = ['VAN','O']
df['NewName'] = df['LastName'].str.replace("'"," ")
for s in delete_space_after_list[:]:
df['NewName'] = df['NewName'].str.replace(s + ' ', s)
df['NewName'] = df['NewName'].str.replace('-'," ")
df['NewName'] = df['NewName'].str.split().str.get(0)
运行此代码会给我以下结果:
Index LastName NewName
0 VAN HOUTEN VANHOUTEN
1 O'BOYLE OBOYLE
2 ESTEVAN-GONZALEZ ESTEVAN
3 RODRIGO TEIXEIRA RODRIGOTEIXEIRA
4 ESTEVAN GONZALEZ ESTEVANGONZALEZ
5 O ROURKE OROURKE
6 RODRIGO-TEIXEIRA RODRIGO
然而,所需的输出是
Index LastName DesiredName
0 VAN HOUTEN VANHOUTEN
1 O'BOYLE OBOYLE
2 ESTEVAN-GONZALEZ ESTEVAN
3 RODRIGO TEIXEIRA RODRIGO
4 ESTEVAN GONZALEZ ESTEVAN
5 O ROURKE OROURKE
6 RODRIGO-TEIXEIRA RODRIGO
它消除了RODRIGO之后的空间(因为LastName末尾的'O')并将其与'TEIXEIRA'连接,同样消除了ESTEVAN之后的空格(因为'{末尾的'VAN') 1}})并将其与'GONZALEZ'连接起来。但是,它正确地消除了其他名称中的空间。
如何让这段代码正确删除空格,就像它对VAN HOUTEN,O'BOYLE,ESTEVAN-GONZALEZ,O ROURKE和& RODRIGO-TEIXEIRA在ESTEVAN GONZALEZ&之后没有删除空白区域。 RODRIGO TEIXEIRA?
答案 0 :(得分:2)
所以你想删除不那么重要的" name,由名称以O
或VAN
结尾但 O
或VAN
的名称后面的名称定义,并删除其他名字的非字母。
这是正则表达式的工作(或没有它们的漫长而痛苦的工作)
我会通过链接这样的2个正则表达式来做到这一点(因为问题与pandas没有直接关系,所以我放弃了pandas):
data = [{'LastName':'VAN HOUTEN'},
{'LastName':"O'BOYLE"},
{'LastName':'ESTEVAN-GONZALEZ'},
{'LastName':'RODRIGO TEIXEIRA'},
{'LastName':'ESTEVAN GONZALEZ'}, # not ESTEBAN as in your example!
{'LastName':'O ROURKE'},
{'LastName':'RODRIGO-TEIXEIRA'}]
import re
new_data = [re.sub("\W","",re.sub("(.)(O|VAN)\W.*",r"\1\2",v['LastName'])) for v in data]
print(new_data)
结果:
['VANHOUTEN', 'OBOYLE', 'ESTEVAN', 'RODRIGO', 'ESTEVAN', 'OROURKE', 'RODRIGO']
这样:
"(.)(O|VAN)\W.*"
匹配至少一个字符,后跟O
和VAN
前缀,后跟非字母(\W
),其余的,我们跳过(我们只保留了2个第一组):处理不太重要的名称" "\W"
删除空格,短划线,引号...所有非字母数字。比处理第二种情况。答案 1 :(得分:1)
大熊猫解决方案,正则表达不像让 - 弗朗索瓦法布尔那样干净,但它有效。
In [541]: import operator
In [542]: df['LastName'].transform(lambda x: x.replace("[-']", ' ', regex=True) \
...: .replace(r'^((?:O)|(?:VAN)) ', r'\1', regex=True) \
...: .str.split()) \
...: .map(operator.itemgetter(0))
...:
Out[546]:
0 VANHOUTEN
1 OBOYLE
2 ESTEVAN
3 RODRIGO
4 ESTEBAN
5 OROURKE
6 RODRIGO
Name: LastName, dtype: object
replace("[-']", ' ', regex=True)
将所有连字符和冒号转换为空格。
replace(r'^((?:O)|(?:VAN)) ', r'\1', regex=True)
在开始'O'
或'VAN'
后删除空格。
str.split()
分裂空间