2017-02-23 85 views
2

我有一个Dataframe,其中一些列中有多个值,总是用,分隔。熊猫:拆分Colum到分隔符上的n个新列

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 

回答

1

我认为你可以使用list comprehensionstr.splitconcat,然后通过mapjoin和最后replace删除列Multiindex所有空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 
+0

谢谢!此代码工作正常。但是我忘了提及还有其他的栏目并不打算分开。在这种情况下,如何指定要处理的列? – kbecker87

+1

请检查编辑答案。 – jezrael

+0

限制列对我来说不适用于这种方式,如果我只指定那些需要分割的列,所有其他列都会搞砸。使用相同的df与多个列进行测试不起作用... – kbecker87