如何使用正则表达式拆分列以将尾随 CAPS 移动到单独的列中?

Posted

技术标签:

【中文标题】如何使用正则表达式拆分列以将尾随 CAPS 移动到单独的列中?【英文标题】:How can I split columns with regex to move trailing CAPS into a separate column? 【发布时间】:2020-04-25 00:59:22 【问题描述】:

我正在尝试使用正则表达式拆分列,但似乎无法正确拆分。我正在尝试将所有尾随 CAPS 移到单独的列中。所以我得到了所有连续 2-4 个大写字母的大写字母。但是,它只会留下 'Name' 列,而 'Team' 列是空白的。

这是我的代码:

import pandas as pd

url = "https://www.espn.com/nba/stats/player/_/table/offensive/sort/avgAssists/dir/desc"

df = pd.read_html(url)[0].join(pd.read_html(url)[1])
df[['Name','Team']] = df['Name'].str.split('[A-Z]2,4', expand=True)  

我想要这个:

print(df.head(5).to_string())
   RK             Name POS  GP   MIN   PTS  FGM   FGA   FG%  3PM  3PA   3P%  FTM  FTA   FT%  REB   AST  STL  BLK   TO  DD2  TD3    PER
0   1  LeBron JamesLA  SF  35  35.1  24.9  9.6  19.7  48.6  2.0  6.0  33.8  3.7  5.5  67.7  7.9  11.0  1.3  0.5  3.7   28    9  26.10
1   2   Ricky RubioPHX  PG  30  32.0  13.6  4.9  11.9  41.3  1.2  3.7  31.8  2.6  3.1  83.7  4.6   9.3  1.3  0.2  2.5   12    1  16.40
2   3   Luka DoncicDAL  SF  32  32.8  29.7  9.6  20.2  47.5  3.1  9.4  33.1  7.3  9.1  80.5  9.7   8.9  1.2  0.2  4.2   22   11  31.74
3   4   Ben SimmonsPHIL  PG  36  35.4  14.9  6.1  10.8  56.3  0.1  0.1  40.0  2.7  4.6  59.0  7.5   8.6  2.2  0.7  3.6   19    3  19.49
4   5    Trae YoungATL  PG  34  35.1  28.9  9.3  20.8  44.8  3.5  9.4  37.5  6.7  7.9  85.0  4.3   8.4  1.2  0.1  4.8   11    1  23.47

变成这样:

print(df.head(5).to_string())
   RK             Name    Team    POS  GP   MIN   PTS  FGM   FGA   FG%  3PM  3PA   3P%  FTM  FTA   FT%  REB   AST  STL  BLK   TO  DD2  TD3    PER
0   1  LeBron James        LA    SF  35  35.1  24.9  9.6  19.7  48.6  2.0  6.0  33.8  3.7  5.5  67.7  7.9  11.0  1.3  0.5  3.7   28    9  26.10
1   2   Ricky Rubio        PHX    PG  30  32.0  13.6  4.9  11.9  41.3  1.2  3.7  31.8  2.6  3.1  83.7  4.6   9.3  1.3  0.2  2.5   12    1  16.40
2   3   Luka Doncic        DAL    SF  32  32.8  29.7  9.6  20.2  47.5  3.1  9.4  33.1  7.3  9.1  80.5  9.7   8.9  1.2  0.2  4.2   22   11  31.74
3   4   Ben Simmons        PHIL    PG  36  35.4  14.9  6.1  10.8  56.3  0.1  0.1  40.0  2.7  4.6  59.0  7.5   8.6  2.2  0.7  3.6   19    3  19.49
4   5    Trae Young        ATL    PG  34  35.1  28.9  9.3  20.8  44.8  3.5  9.4  37.5  6.7  7.9  85.0  4.3   8.4  1.2  0.1  4.8   11    1  23.47

【问题讨论】:

【参考方案1】:

您可以使用 ^(.*?)([A-Z]+)$^(.*[^A-Z])([A-Z]+)$ 之类的正则表达式将数据提取到两列中:

df[['Name','Team']] = df['Name'].str.extract('^(.*?)([A-Z]+)$', expand=True)

这将保留组“名称”中的最后一个不是大写字母的字符和组“团队”中的最后一个大写字母。

见regex demo #1和regex demo #2

详情

^ - 字符串的开头 (.*?) - 捕获组 1:除换行符之外的任何零个或多个字符,尽可能少 或 (.*[^A-Z]) - 除换行符之外的任何零个或多个字符,尽可能多,直到不是 ASCII 大写字母的最后一个字符(允许后续模式匹配)(请注意,此模式意味着至少有 1最后一个大写字母之前的字符) ([A-Z]+) - 捕获组 2:一个或多个 ASCII 大写字母 $ - 字符串结束。

【讨论】:

【参考方案2】:

我对功能做了一些改动,你可能需要添加re包。

它有点手动,但我希望这就足够了。祝你有美好的一天!

df_obj_skel = dict()
df_obj_skel['Name'] = list()
df_obj_skel['Team'] = list()
for index,row in df.iterrows():
    Name = row['Name']
    Findings = re.search('[A-Z]2,4$', Name)
    Refined_Team = Findings[0]
    Refined_Name = re.sub(Refined_Team + "$", "", Name)
    df_obj_skel['Team'].append(Refined_Team)
    df_obj_skel['Name'].append(Refined_Name)
df_final = pd.DataFrame(df_obj_skel)
print(df_final)

【讨论】:

以上是关于如何使用正则表达式拆分列以将尾随 CAPS 移动到单独的列中?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式删除尾随空格?

Nifi JSON正则表达式

正则表达式将字符串拆分为 char 但具有最大大小

正则表达式拆分文本

正则表达式匹配标签内容,同时省略前导和尾随空格

使用尾随数字的正则表达式信用卡匹配