2017-09-12 18 views

Odpowiedz

6
In [101]: df['label'] = df.apply(lambda x: ''.join(df.columns[x.astype(bool)].tolist()), axis=1) 

In [102]: df 
Out[102]: 
    A B C label 
0 1 0 0  A 
1 1 1 0 AB 
2 0 1 0  B 
3 0 0 1  C 

PS Ja na pewno wybrał @Ted's solution jak to o wiele ładniejszy i dużo dużo dużo szybciej ...

+3

"W [101]:" Zastanawiam się, co jeszcze jest na tym notebooku – GiantsLoveDeathMetal

+1

@GiantsLoveDeathMetal, nasza społeczność Pand dorasta - naprawdę to doceniam! :-) – MaxU

+0

@GiantsLoveDeathMetal Jest to monit terminalu IPython, a nie notebook. Jeśli liczba wynosi 101, oznacza to, że było 100 nieudanych prób uzyskania poprawnej odpowiedzi ... LOL (j/k ;-)) –

18

Oto idiomatyczne i wydajnych rozwiązanie

df['label'] = np.where(df, df.columns, '').sum(axis=1) 

    A B C label 
0 1 0 0  A 
1 1 1 0 AB 
2 0 1 0  B 
3 0 0 1  C 
+1

to jest bardzo eleganckie! – MaxU

+0

Nice one !! ~ :) – Wen

5

lub używając melt i groupby

df1 = df.reset_index().melt('index') 
df1 = df1[df1.value==1] 
df['label'] = df1.groupby('index').variable.sum() 
df 

Out[976]: 
    A B C label 
0 1 0 0  A 
1 1 1 0 AB 
2 0 1 0  B 
3 0 0 1  C 

Lub

df['label'] = df.T.apply(lambda x: ''.join(x.index[x==1]),axis=0) 
df 
Out[984]: 
    A B C label 
0 1 0 0  A 
1 1 1 0 AB 
2 0 1 0  B 
3 0 0 1  C 
+0

Działa, ale jest dość powolny. Zazwyczaj chcesz uniknąć groupby, jeśli to możliwe –

+0

@TedPetrou zobacz mój drugi :) – Wen

+1

@GiantsLoveDeathMetal zacznie zauważać format mojego kodu dzisiaj :) – Wen

4
df = df.assign(label=[''.join([df.columns[n] for n, bool in enumerate(row) if bool]) 
         for _, row in df.iterrows()]) 
>>> df 
    A B C label 
0 1 0 0  A 
1 1 1 0 AB 
2 0 1 0  B 
3 0 0 1  C 

Timings

# Set-up: 
df_ = pd.concat([df] * 10000) 

%%timeit 
# Solution by @Wen 
df1 = df_.reset_index().melt('index') 
df1 = df1[df1.value==1] 
df['label'] = df1.groupby('index').variable.sum() 
# 10 loops, best of 3: 47.6 ms per loop 

%%timeit 
# Solution by @MaxU 
df_['label'] = df_.apply(lambda x: ''.join(df_.columns[x.astype(bool)].tolist()), axis=1) 
# 1 loop, best of 3: 4.99 s per loop 

%%timeit 
# Solution by @TedPetrou 
df_['label'] = np.where(df_, df_.columns, '').sum(axis=1) 
# 100 loops, best of 3: 12.5 ms per loop 

%%timeit 
# Solution by @Alexander 
df_['label'] = [''.join([df_.columns[n] for n, bool in enumerate(row) if bool]) for _, row in df_.iterrows()] 
# 1 loop, best of 3: 3.75 s per loop 

%%time 
# Solution by @PiRSquared 
df_['label'] = df_.dot(df_.columns) 
# CPU times: user 18.1 ms, sys: 706 µs, total: 18.8 ms 
# Wall time: 18.9 ms 
+0

Tylko te same czasy. Bardzo fajny. –

13

Korzystanie dot

df.assign(label=df.dot(df.columns)) 

    A B C label 
0 1 0 0  A 
1 1 1 0 AB 
2 0 1 0  B 
3 0 0 1  C 

samo przy użyciu podstawowych tablic numpy

df.assign(label=df.values.dot(df.columns.values)) 

    A B C label 
0 1 0 0  A 
1 1 1 0 AB 
2 0 1 0  B 
3 0 0 1  C 
+1

Jest to również bardzo inteligentne! – MaxU

+1

'df.dot (df.columns)' jest bardzo ładne. – Alexander

+0

Wow, nie wiedziałem, że możesz pomnożyć liczby całkowite i obiekty –

Powiązane problemy