2017-02-23 4 views
2

Ich habe ein Dataframe wo in einigen Spalten gibt es mehrere Werte, immer durch , getrennt.Pandas: Split Colum in n neue Spalten auf Trennzeichen

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 

Wie kann ich teilen Sie die Spalten n Spalten mit jeweils nur eine Variable enthält?

zB:

  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 

Antwort

1

Ich glaube, Sie list comprehension mit str.split und concat, dann entfernen Multiindex in Spalten von map und join und letzten replace all leer strings und None-NaN verwenden können:

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 

Wenn in DataFrames sind eine andere Spalten:

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 

zuletzt können Sie concat Spalten, die nicht gesplittet werden:

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

Dank! Dieser Code funktioniert gut. Ich habe jedoch vergessen zu erwähnen, dass es andere Spalten gibt, die nicht getrennt werden sollen. Wie würde man die Spalten spezifizieren, die in diesem Fall verarbeitet werden? – kbecker87

+1

überprüfen Sie bitte die bearbeitete Antwort. – jezrael

+0

Die Beschränkung auf Spalten funktioniert auf diese Weise nicht. Wenn ich nur die Spalten spalte, die ich teilen muss, werden alle anderen Spalten durcheinander gebracht. Die Verwendung des gleichen Df mit einer weiteren Spalte für Testzwecke funktioniert nicht ... – kbecker87

Verwandte Themen