保留完整的姓氏,在熊猫栏中获得名字的首字母缩写(如果有的话,还有中间名)



我有一个熊猫数据框,其中有一列表示几位网球运动员的姓氏和名字,如下所示:

| Player              | 
|---------------------|
0  | 'Roddick Andy'      |
1  | 'Federer Roger'     |
2  | 'Tsonga Jo Wilfred  |

我想保留完整的姓氏,如果有的话,可以得到名字的首字母和中间名。所以熊猫栏应该像下面这样:

| Player            | 
|-------------------|
0  | 'Roddick A.'      |
1  | 'Federer R.'      |
2  | 'Tsonga J.W.'     | N.B. J.W. with no space

有人有什么建议吗?感谢

以下是一种使用str.extractallgroupby的方法:

(df.Player
.str.extractall('(?P<Surname>w*)s(?P<Name>w*)')
.groupby(level=0)
.agg({'Surname':'first',
'Name': lambda x: x.str[0].add('.').sum()
})
.agg(' '.join, axis=1)
)

输出:

0     Roddick A.
1     Federer R.
2    Tsonga J.W.
dtype: object

您可以按如下方式使用df.replace

import pandas as pd 
df = pd.DataFrame({'Player':['Roddick Andy', 'Federer Roger', 'Tsonga Jo Wilfred']})
df = df.replace(r'(?<=sw)w+s?', value = '.', regex = True)
print(df)

正则表达式:(?<=sw)w+s?

  • w+-至少匹配一个单词字符
  • (?<=sw)-正向查找(第一步前面必须有一个空格和任何一个单词字符
  • s?-第一步后面是可选的空白

结果:

Player
0   Roddick A.
1   Federer R.
2  Tsonga J.W.

编辑:

选项1:

为了交换两个声母,我们可以(为了保持使用正则表达式的想法(添加另一个df.replace,以及第二个正则表达式。

import pandas as pd 
df = pd.DataFrame({'Player':['Roddick Andy', 'Federer Roger', 'Tsonga Jo Wilfred']})
df = df.replace(r'(?<=sw)w+s?', value = '.', regex = True)
df = df.replace(r'(.(?=.).)(.(?=.).)?', value = r'21', regex = True)
print(df)

正则表达式:(.(?=.).)(.(?=.).)?

  • (.(?=.).)-捕获组1:匹配后面跟着(正向前瞻(文字点的任何字符(.(,包括匹配点
  • (.(?=.).)?-捕获组2:可选(?(捕获组,与捕获组1完全匹配

以上内容不是很动态。但当最多有两个首字母缩写时,它会很好地工作。也可以很容易地附加在上面,但是下面的选项会更动态。

选项2:

在你继续之前,我可以说我对Python还很陌生,所以我相信我在这里所做的事情可以缩短/做得简单得多。

这里的想法是split并结束数据帧,然后将除第一列外的所有列反转为join,然后将它们重新组合为数据帧中的一列,然后我们可以再次应用df.replace

import pandas as pd
df = pd.DataFrame({'Player':['Roddick Andy', 'Federer Roger', 'Tsonga Jo Wilfred']})
df = df.Player.str.split(None, expand=True).iloc[:, ::-1]
df = df[[list(df.columns)[-1]] + list(df.columns)[:-1]]
df = df[df.columns[0:]].apply(lambda x: ' '.join(x.dropna().astype(str)), axis=1)
df = df.replace(r'(?<=sw)w+s?', value = '.', regex = True)
print(df)

结果:

Player
0   Roddick A.
1   Federer R.
2  Tsonga W.J.

假设每个姓氏都是一个单词的姓氏:

def shorten_name(name):
name_as_list = name.split(" ")
last_name = name_as_list[-1]
first_names = ".".join([w[0] for w in name_as_list[:-1]]) + "."
return (last_name, first_names)

像这样使用:

last_name, first_names_shortened = shorten_name("Jo Wilfried Tsonga")

最新更新