2017-09-12 27 views

Trả lời

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 i chắc chắn sẽ chọn @Ted's solution như nó đẹp hơn nhiều và nhiều hơn thế nhiều ... nhanh hơn

+3

"Trong [101]:" Tôi tự hỏi có gì khác trên sổ ghi chép đó – GiantsLoveDeathMetal

+1

@GiantsLoveDeathMetal, cộng đồng Pandas của chúng tôi đang phát triển - thực sự đánh giá cao điều này! :-) – MaxU

+0

@GiantsLoveDeathMetal Đây là lời nhắc thiết bị đầu cuối IPython, không phải sổ ghi chép. Nếu con số là 101, điều đó có nghĩa là có 100 lần không thành công để nhận được câu trả lời đúng ... LOL (j/k ;-)) –

18

Dưới đây là một giải pháp thành ngữ và performant

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

điều này rất thanh lịch! – MaxU

+0

Đẹp nhất !! ~ :) – Wen

5

Hoặc sử dụng meltgroupby

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 

Hoặc

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

Hoạt động nhưng khá chậm. Bạn thường muốn tránh groupby nếu có thể –

+0

@TedPetrou thấy số thứ hai của tôi :) – Wen

+1

@GiantsLoveDeathMetal sẽ bắt đầu nhận thấy định dạng mã của tôi hôm nay :) – 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 

Thời gian

# 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

Cũng giống như thời gian. Rất tuyệt. –

13

Sử dụng 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 

Cùng một điều sử dụng mảng NumPy tiềm ẩn

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

Điều này cũng rất thông minh! – MaxU

+1

'df.dot (df.columns)' rất đẹp. – Alexander

+0

Ồ, tôi không biết bạn có thể nhân số nguyên và đối tượng –

Các vấn đề liên quan