【问题标题】:Pandas Split column into multiple columns by multiple string delimitersPandas 通过多个字符串分隔符将列拆分为多列
【发布时间】:2020-09-14 06:58:40
【问题描述】:

我有一个数据框:

id    info
1     Name: John Age: 12 Sex: Male
2     Name: Sara Age: 22 Sex: Female
3     Name: Mac Donald Age: 32 Sex: Male

我希望将信息列拆分为 3 列,以便我得到最终输出:

id  Name      Age   Sex
1   John      12   Male
2   Sara      22   Female
3 Mac Donald  32   Male

我尝试使用 pandas 拆分功能。

df[['Name','Age','Sex']] = df.info.split(['Name'])

我可能需要多次执行此操作才能获得所需的输出。

有没有更好的方法来实现这一点?

PS:info 列还包含NaN 值

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    对命名组使用正则表达式。

    例如:

    df = pd.DataFrame({"Col": ['Name: John Age: 12 Sex: Male', 'Name: Sara Age: 22 Sex: Female', 'Name: Mac Donald Age: 32 Sex: Male']})
    df = df['Col'].str.extract(r"Name:\s*(?P<Name>[A-Za-z\s]+)\s*Age:\s*(?P<Age>\d+)\s*Sex:\s*(?P<Sex>Male|Female)") # Or if spacing is standard use df['Col'].str.extract(r"Name: (?P<Name>[A-Za-z\s]+) Age: (?P<Age>\d+) Sex: (?P<Sex>Male|Female)")
    print(df)
    

    输出:

              Name Age     Sex
    0        John   12    Male
    1        Sara   22  Female
    2  Mac Donald   32    Male
    

    【讨论】:

    • 此解决方案创建空白。如果您执行df['Name'].to_list(),您将返回:['John ', 'Sara ', 'Mac Donald '] 一个简单的str.strip() 可以解决此问题,因为正则表达式会变得更加激烈。
    【解决方案2】:

    正则表达式很难写/读,所以你可以用, 替换你想要分成新列的地方,并使用str.split() 并传递expand=True。您需要将结果设置回您使用 df[['Name', 'Age', 'Sex']] 创建的三个新列:

    df[['Name', 'Age', 'Sex']] = (df['info'].replace(['Name: ', ' Age: ', ' Sex: '], ['',',',','], regex=True)
                                  .str.split(',', expand=True))
    df
    
    Out[1]: 
       id                                info        Name Age     Sex
    0   1        Name: John Age: 12 Sex: Male        John  12    Male
    1   2      Name: Sara Age: 22 Sex: Female        Sara  22  Female
    2   3  Name: Mac Donald Age: 32 Sex: Male  Mac Donald  32    Male
    

    【讨论】:

      【解决方案3】:

      一个快速的oneliner可以是

      df[['Name', 'Age', 'Sex']] = df['info'].str.split('\s?\w+:\s?', expand=True).iloc[:, 1:]
      

      使用someword: 拆分,然后添加新列。

      【讨论】:

      • 啊啊,我忘了\w+。好的!但是,这会产生空白,因此您需要执行 str.strip() 或改进正则表达式。对于初学者,您可以使用\w+: 而不是\w+:,但这只会去掉最后一个空格。
      • Strip 无济于事,也不会产生空白。额外的列是由于字符串以拆分字符串开头的事实。 @大卫埃里克森
      • 如果你做df['Name'].to_list()或df['Age'].to_list(),你会看到每个字符串前后都有一个' '
      • 哦!你的意思是在我得到结果之后。是的,strip 应该解决这个问题。
      • 是的,例如df['Age'].to_list() 返回:[' 12 ', ' 22 ', ' 32 '] Rakesh 的回答中存在类似问题,仅针对Name 列。
      【解决方案4】:
        def process_row(row):
              items = row.info.split(' ')
              row['Name']=str(items[1]).strip()
              row['Age']=str(items[3]).strip()
              row['Sex']=str(items[5]).strip()
              return row
      
        df=pd.DataFrame({"info": ['Name: John Age: 12 Sex: Male', 'Name: Sara Age: 22 Sex: 
           Female', 'Name: Mac Donald Age: 32 Sex: Male']})
        df['Name']=pd.NA #empty cell
        df['Age']=pd.NA #empty cell
        df['Sex']=pd.NA #empty cell
      
        df[['info','Name','Age','Sex']]=df.apply(process_row, axis=1, result_type="expand")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-01-13
        • 2021-03-05
        • 2018-03-17
        • 1970-01-01
        • 2013-10-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多