为了账号安全,请及时绑定邮箱和手机立即绑定

如何用大写字母拆分 pandas 数据框中的字符串

如何用大写字母拆分 pandas 数据框中的字符串

繁星淼淼 2023-08-15 18:40:19
我正在处理一些 NFL 数据,数据框中有一列,如下所示:0         Lamar JacksonL. Jackson BAL1     Patrick Mahomes IIP. Mahomes KC2         Dak PrescottD. Prescott DAL3              Josh AllenJ. Allen BUF4         Russell WilsonR. Wilson SEA每个单元格中有 3 位信息 - FullName,ShortName我Team希望为其创建新列。预期输出:         FullName                ShortName        Team0         Lamar Jackson           L. Jackson        BAL1         Patrick Mahomes II      P. Mahomes        KC2         Dak Prescott            D. Prescott       DAL3         Josh Allen              J. Allen          BUF4         Russell Wilson          R. Wilson         SEA我已经设法得到了,Team但我不太确定如何在一行中完成所有这三个操作。我正在考虑通过查找前一个字符来分割字符串,fullstop但是出现了一些名称,例如:Anthony McFarland Jr.A. McFarland PIT有多个句号。有人知道解决这个问题的最佳方法吗?谢谢!
查看完整描述

4 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

pandas Series str.extract 方法就是您所寻找的。该正则表达式适用于您提出的所有情况,尽管可能还有一些其他边缘情况。


df = pd.DataFrame({

    "bad_col": ["Lamar JacksonL. Jackson BAL", "Patrick Mahomes IIP. Mahomes KC", 

                "Dak PrescottD. Prescott DAL", "Josh AllenJ. Allen BUF", 

                "Josh AllenJ. Allen SEA", "Anthony McFarland Jr.A. McFarland PIT"],

})


print(df)

                                 bad_col

0            Lamar JacksonL. Jackson BAL

1        Patrick Mahomes IIP. Mahomes KC

2            Dak PrescottD. Prescott DAL

3                 Josh AllenJ. Allen BUF

4                 Josh AllenJ. Allen SEA

5  Anthony McFarland Jr.A. McFarland PIT



pattern = r"(?P<full_name>.+)(?=[A-Z]\.)(?P<short_name>[A-Z]\.\s.*)\s(?P<team>[A-Z]+)"

new_df = df["bad_col"].str.extract(pattern, expand=True)

print(new_df)

               full_name    short_name team

0          Lamar Jackson    L. Jackson  BAL

1     Patrick Mahomes II    P. Mahomes   KC

2           Dak Prescott   D. Prescott  DAL

3             Josh Allen      J. Allen  BUF

4             Josh Allen      J. Allen  SEA

5  Anthony McFarland Jr.  A. McFarland  PIT

分解该正则表达式:

(?P<full_name>.+)(?=[A-Z]\.)(?P<short_name>[A-Z]\.\s.*)\s(?P<team>[A-Z]+)
  • (?P<full_name>.+)(?=[A-Z]\.) 捕获任何字母,直到我们看到大写字母后跟句号/句号,我们使用前瞻 (?=...) 来不消耗大写字母和句号,因为字符串的这一部分属于短名称

  • (?P<short_name>[A-Z]\.\s.*.)\s 捕获一个大写字母(玩家的第一个首字母),然后是句号(第一个首字母后面的句点),然后是一个空格(第一个首字母和姓氏之间),然后是所有字符,直到我们点击空格(玩家的姓氏) )。该空间不包含在捕获组中。

  • (?P<team>[A-Z]+) 捕获字符串中所有剩余的大写字母(最终成为玩家团队)

您可能已经注意到,我使用了由 (?Ppattern) 结构表示的命名捕获组。在 pandas 中,捕获组的名称将成为列的名称,该组中捕获的任何内容将成为该列中的值。

现在将新的数据框加入到我们原来的数据框中,完成一圈:

df = df.join(new_df)

print(df)

                                 bad_col              full_name    short_name  \

0            Lamar JacksonL. Jackson BAL          Lamar Jackson    L. Jackson   

1        Patrick Mahomes IIP. Mahomes KC     Patrick Mahomes II    P. Mahomes   

2            Dak PrescottD. Prescott DAL           Dak Prescott   D. Prescott   

3                 Josh AllenJ. Allen BUF             Josh Allen      J. Allen   

4                 Josh AllenJ. Allen SEA             Josh Allen      J. Allen   

5  Anthony McFarland Jr.A. McFarland PIT  Anthony McFarland Jr.  A. McFarland   


  team  

0  BAL  

1   KC  

2  DAL  

3  BUF  

4  SEA  

5  PIT  


查看完整回答
反对 回复 2023-08-15
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

我的猜测是短名称不会包含句号。因此,您可以搜索从行尾开始的第一个句号。因此,从句号之前的一个字符到第一个空格都是您的简称。句点前一个字母之前的任何内容都将是全名。



查看完整回答
反对 回复 2023-08-15
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

这可能会有所帮助。


import re


name = 'Anthony McFarland Jr.A. McFarland PIT'


short_name = re.findall(r'(\w\.\s[\w]+)\s[\w]{3}', name)[0]

full_name = name.replace(short_name, "")[:-4]

team = name[-3:]


print(short_name)

print(full_name)

print(team)

输出:


A. McFarland

Anthony McFarland Jr.

PIT


查看完整回答
反对 回复 2023-08-15
?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

import pandas as pd

import numpy as np


df = pd.DataFrame({'players':['Lamar JacksonL. Jackson BAL', 'Patrick Mahomes IIP. Mahomes KC', 

                         'Anthony McFarland Jr.A. McFarland PIT']})


def splitName(name):

    last_period_pos = np.max(np.where(np.array(list(name)) == '.'))

    full_name = name[:(last_period_pos - 1)]

    short_name_team = name[(last_period_pos - 1):]

    team_pos = np.max(np.where(np.array(list(short_name_team)) == ' '))

    short_name = short_name_team[:team_pos]

    team = short_name_team[(team_pos + 1):]

    return full_name, short_name, team


df['full_name'], df['short_name'], df['team'] = zip(*df.players.apply(splitName))


查看完整回答
反对 回复 2023-08-15
  • 4 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信