如何使用大写字母在熊猫数据框中拆分字符串

时间:2020-09-17 04:05:26

标签: python pandas

我正在处理一些NFL数据,并且在数据框中有一个看起来像这样的列:

@Override
 public void applyOverrideConfiguration(Configuration overrideConfiguration) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
    // update overrideConfiguration with your locale  
    setLocale(overrideConfiguration) // you need to implement this
}
super.applyOverrideConfiguration(overrideConfiguration);
} 

每个单元格中都有3位信息-0 Lamar JacksonL. Jackson BAL 1 Patrick Mahomes IIP. Mahomes KC 2 Dak PrescottD. Prescott DAL 3 Josh AllenJ. Allen BUF 4 Russell WilsonR. Wilson SEA FullNameShortName,我希望为其创建新的列。

预期输出:

Team

我已经设法获得了 FullName ShortName 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 Russell Wilson R. Wilson SEA ,但我不太确定如何在一行中完成全部三个操作。

我本来想通过从Team中查找前一个字符来分割字符串,但是出现了一些名称,例如:

fullstop

有多个句点。

有人知道解决此问题的最佳方法吗?谢谢!

4 个答案:

答案 0 :(得分:2)

您正在寻找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)结构表示的命名捕获组。在大熊猫中,捕获组的名称将成为该列的名称,而该组中捕获的任何内容将成为该列中的值。

现在将新的数据框加入到我们的原始数据框中来成为一个完整的圈子:

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  

答案 1 :(得分:0)

这可能有帮助。

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

答案 2 :(得分:0)

我的猜测是,短名称不会包含句号。因此,您可以从行尾搜索第一个句号。因此,从句号之前的一个字符一直到第一个空格是您的简称。在句号之前一个字母之前的所有内容都将是FullName。

答案 3 :(得分:0)

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))