Pandas: 在分隔符上将列拆分为 n 个新列

Pandas: Split Colum into n new columns on separator

我有一个 Dataframe,其中某些列中有多个值,总是由 , 分隔。

df = pd.DataFrame([['', 'mariachi', 'mexico, united states'],
                   ['', 'jazz, rap', 'united states'],
                   ['', '', 'spain'],
                   ['jimi hendrix, john lennon', 'rock', ''],
                   ['spirit', '', 'united states'],
                   ['', 'latin', 'united states'],
                   ['', '', ''],
                   ['speak', '', 'mexico, united states']], 
                   columns=['Musician', 'Genre', 'Country'])


                        Musician          Genre                   Country
   1                         NaN       mariachi     mexico, united states
   2                         NaN      jazz, rap             united states
   3                         NaN            NaN                     spain
   4   jimi hendrix, john lennon           rock                       NaN
   5                      spirit            NaN             united states
   6                         NaN          latin             united states
   7                         NaN            NaN                       NaN
   8                       speak            NaN     mexico, united states

如何将列拆分为 n 列,每列仅包含一个变量?

例如:

          Musician       Musician2          Genre      Genre2          Country         Country2
   1           NaN             NaN       mariachi         NaN           mexico    united states
   2           NaN             NaN           jazz         rap    united states              NaN
   3           NaN             NaN            NaN         NaN            spain              NaN
   4  jimi hendrix     john lennon           rock         NaN              NaN              NaN
   5        spirit             NaN            NaN         NaN    united states              NaN
   6           NaN             NaN          latin         NaN    united states              NaN
   7           NaN             NaN            NaN         NaN              NaN              NaN
   8         speak             NaN            NaN         NaN           mexico    united states

我想你可以使用 list comprehensionstr.split and concat, then remove Multiindex in columns by map and join and last replace 全空 stringsNoneNaN:

cols = ['Musician','Genre','Country']
df = pd.concat([df[x].str.split(',', expand=True) for x in cols], axis=1, keys=df.columns)
df.columns = df.columns.map(lambda x: '_'.join((x[0], str(x[1]))))
df = df.replace({'':np.nan, None:np.nan})
print (df)
     Musician_0    Musician_1   Genre_0 Genre_1      Country_0       Country_1
0           NaN           NaN  mariachi     NaN         mexico   united states
1           NaN           NaN      jazz     rap  united states             NaN
2           NaN           NaN       NaN     NaN          spain             NaN
3  jimi hendrix   john lennon      rock     NaN            NaN             NaN
4        spirit           NaN       NaN     NaN  united states             NaN
5           NaN           NaN     latin     NaN  united states             NaN
6           NaN           NaN       NaN     NaN            NaN             NaN
7         speak           NaN       NaN     NaN         mexico   united states

如果在 DataFrames 中还有其他列:

df = pd.DataFrame([['', 'mariachi', 'mexico, united states',5],
                   ['', 'jazz, rap', 'united states',8],
                   ['', '', 'spain',8],
                   ['jimi hendrix, john lennon', 'rock', '',1],
                   ['spirit', '', 'united states',7],
                   ['', 'latin', 'united states',1],
                   ['', '', '',0],
                   ['speak', '', 'mexico, united states',3]], 
                   columns=['Musician', 'Genre', 'Country', 'Val'])
print (df)
                    Musician      Genre                Country  Val
0                              mariachi  mexico, united states    5
1                             jazz, rap          united states    8
2                                                        spain    8
3  jimi hendrix, john lennon       rock                           1
4                     spirit                     united states    7
5                                 latin          united states    1
6                                                                 0
7                      speak             mexico, united states    3

最后你可以 concat 列,它们没有拆分:

cols = ['Musician','Genre','Country']
df1 = pd.concat([df[x].str.split(',', expand=True) for x in cols], axis=1, keys=df.columns)
df1.columns = df1.columns.map(lambda x: '_'.join((x[0], str(x[1]))))
df1 = df1.replace({'':np.nan, None:np.nan})
print (df1)
     Musician_0    Musician_1   Genre_0 Genre_1      Country_0       Country_1
0           NaN           NaN  mariachi     NaN         mexico   united states
1           NaN           NaN      jazz     rap  united states             NaN
2           NaN           NaN       NaN     NaN          spain             NaN
3  jimi hendrix   john lennon      rock     NaN            NaN             NaN
4        spirit           NaN       NaN     NaN  united states             NaN
5           NaN           NaN     latin     NaN  united states             NaN
6           NaN           NaN       NaN     NaN            NaN             NaN
7         speak           NaN       NaN     NaN         mexico   united states

df2 = pd.concat([df1, df.drop(cols, axis=1)],axis=1)
print (df2)
     Musician_0    Musician_1   Genre_0 Genre_1      Country_0  \
0           NaN           NaN  mariachi     NaN         mexico   
1           NaN           NaN      jazz     rap  united states   
2           NaN           NaN       NaN     NaN          spain   
3  jimi hendrix   john lennon      rock     NaN            NaN   
4        spirit           NaN       NaN     NaN  united states   
5           NaN           NaN     latin     NaN  united states   
6           NaN           NaN       NaN     NaN            NaN   
7         speak           NaN       NaN     NaN         mexico   

        Country_1  Val  
0   united states    5  
1             NaN    8  
2             NaN    8  
3             NaN    1  
4             NaN    7  
5             NaN    1  
6             NaN    0  
7   united states    3