【问题标题】:Adding a function to a string split command in Pandas在 Pandas 中向字符串拆分命令添加函数
【发布时间】:2017-10-27 23:58:13
【问题描述】:

我有一个包含 20 列左右的数据框。其中一列称为“director_name”,并具有诸如“John Doe”或“Jane Doe”之类的值。我想把它分成两列,“First_Name”和“Last_Name”。当我运行以下命令时,它按预期工作并将字符串分成 2 列:

data[['First_Name', 'Last_Name']] = data.director_name.str.split(' ', expand 
= True) 
data

First_Name    Last_Name
John          Doe

它很好用,但是当我在“director_name”下有 NULL (NaN) 值时它不起作用。它抛出以下错误:

'Columns must be same length as key'

我想添加一个检查值是否为 != null 的函数,然后执行上面列出的命令,否则为 First_Name 和 'Last_Name' 输入 'NA'

任何想法我会怎么做?

编辑:

我刚刚检查了文件,但不确定是否为 NULL。我有一些 3-4 个字符串长的名字。即

John Allen Doe
John Allen Doe Jr

也许我不能把它分成 First_Name 和 Last_Name。

嗯嗯

【问题讨论】:

  • 这对我有用。你用的是什么版本的 pandas/python?
  • Python 3,熊猫 0.20.1。当你有空值时它有效吗?我认为这就是错误显示给我的原因。也许是其他原因?文件有 5k 条记录,当我执行 .head(10) 并且所有值都存在时,它可以工作,当我将它打开到整个文件('director_name' 中有 NULL 值)时,它不会
  • 该错误是因为某些字段会有多个空格,我已经更新了您上一个问题的答案以处理该问题
  • @JD2775,我也试过了,效果很好。
  • 如果有一个值说 'Robert Downey Jr',此代码将抛出错误,因为它需要两个字段,解决方案被拆分并取前两个值。df['First_Name'] = df .name.str.split(' ', expand = True)[0] df['Last_Name'] = df.name.str.split(' ', expand = True)[1]

标签: python pandas


【解决方案1】:

这里有一种方法是拆分并选择前两个值作为名字和姓氏

    Id  name
0   1   James Cameron
1   2   Martin Sheen
2   3   John Allen Doe
3   4   NaN


df['First_Name'] = df.name.str.split(' ', expand = True)[0]
df['Last_Name'] = df.name.str.split(' ', expand = True)[1]

你得到

    Id  name            First_Name  Last_Name
0   1   James Cameron   James       Cameron
1   2   Martin Sheen    Martin      Sheen
2   3   John Allen Doe  John        Allen
3   4   NaN             NaN         None

【讨论】:

  • 太完美了。谢谢A-Z
【解决方案2】:

使用str.split(无参数,因为默认分隔符为空格)和indexing with str按位置选择列表:

print (df.name.str.split())
0      [James, Cameron]
1       [Martin, Sheen]
2    [John, Allen, Doe]
3                   NaN
Name: name, dtype: object

df['First_Name'] = df.name.str.split().str[0]
df['Last_Name'] = df.name.str.split().str[1]

#data borrow from A-Za-z answer
print (df)
   Id            name First_Name Last_Name
0   1   James Cameron      James   Cameron
1   2    Martin Sheen     Martin     Sheen
2   3  John Allen Doe       John     Allen
3   4             NaN        NaN       NaN

也可以使用参数n 来选择第二个或前两个名字:

df['First_Name'] = df.name.str.split().str[0]
df['Last_Name'] = df.name.str.split(n=1).str[1]
print (df)
   Id            name First_Name  Last_Name
0   1   James Cameron      James    Cameron
1   2    Martin Sheen     Martin      Sheen
2   3  John Allen Doe       John  Allen Doe
3   4             NaN        NaN        NaN

str.rstrip的解决方案

df['First_Name'] = df.name.str.rsplit(n=1).str[0]
df['Last_Name'] = df.name.str.rsplit().str[-1]
print (df)
   Id            name  First_Name Last_Name
0   1   James Cameron       James   Cameron
1   2    Martin Sheen      Martin     Sheen
2   3  John Allen Doe  John Allen       Doe
3   4             NaN         NaN       NaN

【讨论】:

  • 规则很简单——如果使用标准的 pandas 函数,NaNs 可以很好地工作;)祝你好运!
【解决方案3】:
df['First_Name'] = df.name.str.split(' ', expand = True)[0]
df['Last_Name'] = df.name.str.split(' ', expand = True)[1]

应该这样做

【讨论】:

    【解决方案4】:

    这应该可以解决您的问题

    设置

    data= pd.DataFrame({'director_name': {0: 'John Doe', 1: np.nan, 2: 'Alan Smith'}})
    
    data
    Out[457]: 
      director_name
    0      John Doe
    1           NaN
    2    Alan Smith
    

    解决方案

    #use a lambda function to check nan before splitting the column.
    data[['First_Name', 'Last_Name']] = data.apply(lambda x: pd.Series([np.nan,np.nan] if pd.isnull(x.director_name) else x.director_name.split()), axis=1)
    
    data
    Out[446]: 
      director_name First_Name Last_Name
    0      John Doe       John       Doe
    1           NaN        NaN       NaN
    2    Alan Smith       Alan     Smith
    

    如果你只需要取前 2 个名字,你可以这样做:

    data[['First_Name', 'Last_Name']] = data.apply(lambda x: pd.Series([np.nan,np.nan] if pd.isnull(x.director_name) else x.director_name.split()).iloc[:2], axis=1)
    

    【讨论】:

    • 谢谢艾伦!记下所有这些解决方案以供将来参考。
    猜你喜欢
    • 2010-11-23
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多