6 回答

TA貢獻2003條經驗 獲得超2個贊
你可以用點來實現它:
? df = pd.DataFrame(
? ? {
? ? ? ? 'A': [0,0,1],
? ? ? ? 'B': [1,0,0],
? ? ? ? 'C': [0,0,0,],
? ? ? ? 'D': [1,0,1],
? ? ? ? 'F': [1,0,1]
? ? }
)
df['new_column'] = df.dot(df.columns).str.join(",")
? ? A? ?B? ?C? ?D? ?F? ?new_column
0? ?0? ?1? ?0? ?1? ?1? ?B,D,F
1? ?0? ?0? ?0? ?0? ?0? ?
2? ?1? ?0? ?0? ?1? ?1? ?A,D,F
更新:對于包含多個字母的列,@BEN_YO 提出了一個非常好的解決方案:
df.dot(df.columns+',').str[:-1]

TA貢獻1836條經驗 獲得超3個贊
如果列名更像一個字符,請使用DataFrame.dot
向列名添加分隔符并最后從右側刪除Series.str.rstrip
:
df['new_column'] = df.dot(df.columns + ',').str.rstrip(",")
#alternative
#df['new_column'] = (df @ (df.columns + ',')).str.rstrip(",")
print (df)
? ?A? B? C? D? F new_column
0? 0? 1? 0? 1? 1? ? ? B,D,F
1? 0? 0? 0? 0? 0? ? ? ? ? ?
2? 1? 0? 0? 1? 1? ? ? A,D,F
df = pd.DataFrame({
? ? ? ? 'col1': [0,0,1],
? ? ? ? 'col2': [1,0,0],
? ? ? ? 'col3': [0,0,0,],
? ? ? ? 'col4': [1,0,1],
? ? ? ? 'col5': [1,0,1]})
df['new_column'] = df.dot(df.columns + ',').str.rstrip(",")
#alternative
#df['new_column'] = (df @ (df.columns + ',')).str.rstrip(",")
print (df)
? ?col1? col2? col3? col4? col5? ? ? new_column
0? ? ?0? ? ?1? ? ?0? ? ?1? ? ?1? col2,col4,col5
1? ? ?0? ? ?0? ? ?0? ? ?0? ? ?0? ? ? ? ? ? ? ??
2? ? ?1? ? ?0? ? ?0? ? ?1? ? ?1? col1,col4,col5
替代解決方案:
cols = df.columns.to_numpy()
df["new_column"] = [', '.join(cols[x]) for x in df.to_numpy().astype(bool)]
性能:
sammywemmy無法使用第一個解決方案,因為有 50 列,所以有些列有 2 個或更多字母。也是footfalcon創建列表的解決方案,所以也不要測試。
df = pd.DataFrame({
? ? ? ? 'A': [0,0,1],
? ? ? ? 'B': [1,0,0],
? ? ? ? 'C': [0,0,0,],
? ? ? ? 'D': [1,0,1],
? ? ? ? 'E': [1,0,1]})
[30000 rows x 50 columns]
df = pd.concat([df] * 10, ignore_index=True, axis=1)
df = pd.concat([df] * 10000, ignore_index=True).add_prefix('col')
最快的是列表理解解決方案,但樣本數據只有 10 毫秒,然后是真正快速的dot解決方案,最后是apply解決方案:
In [70]: %%timeit
? ? ...: cols = df.columns.to_numpy()
? ? ...: df["new_column"] = [', '.join(cols[x]) for x in df.to_numpy().astype(bool)]
? ? ...:?
128 ms ± 443 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
#for testing are values converted to boolean (else test fail)
In [72]: %timeit df['new_column'] = df.astype(bool).dot(df.columns + ',').str.rstrip(",")
138 ms ± 1.95 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
#Dishin H Goyani
In [73]: %timeit df["New_column"] = df.apply(lambda x: ','.join(df.columns[x==1]), axis=1)
3.98 s ± 129 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#Akshay Sehgal
In [75]: %timeit df['new_column'] = df.apply(lambda x: ', '.join(list(x[x!=0].index)), axis=1)
11 s ± 349 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#Rajith Thennakoon
In [78]: %%timeit
? ? ...: df["new_column"] = df.apply(lambda x: (pd.DataFrame(x[x==1]).index.values),axis=1)
? ? ...: df["new_column"] = df["new_column"].apply(lambda x: ','.join(map(str, x)))
? ? ...:?
? ? ...:?
25.9 s ± 709 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

TA貢獻1784條經驗 獲得超7個贊
不確定這是否是最佳解決方案,但它可以完成工作:
import pandas as pd
df = pd.DataFrame(
{
'A': [0,0,1],
'B': [1,0,0],
'C': [0,0,0,],
'D': [1,0,1],
'F': [1,0,1]
}
)
df1 = df.T
new_cells = []
for c in df1.columns:
new_cells.append(df1[df1[c] == 1].index.tolist())
df['New_column'] = new_cells
輸出:
A B C D F New_column
0 0 1 0 1 1 [B, D, F]
1 0 0 0 0 0 []
2 1 0 0 1 1 [A, D, F]

TA貢獻1865條經驗 獲得超7個贊
如果你有 python >= 3.5,你可以使用 matmul 運算符來做一個點積——
df['new_column'] = (df @ df.columns).str.join(', ')
? ?A? B? C? D? E new_column
0? 0? 1? 0? 1? 1? ? B, D, E
1? 0? 0? 0? 0? 0? ? ? ? ? ?
2? 1? 0? 0? 1? 1? ? A, D, E
或者您可以使用applyaxis=1 解決此問題,如下所示 -
df['new_column'] = df.apply(lambda x: ', '.join(list(x[x!=0].index)), axis=1)
? ?A? B? C? D? E new_column
0? 0? 1? 0? 1? 1? ? B, D, E
1? 0? 0? 0? 0? 0? ? ? ? ? ?
2? 1? 0? 0? 1? 1? ? A, D, E

TA貢獻1831條經驗 獲得超10個贊
您可以使用applywith lambdafunction onaxis=1
df["New_column"] = df.apply(lambda x: ','.join(df.columns[x==1]), axis=1)
df
A B C D F New_column
0 0 1 0 1 1 B,D,F
1 0 0 0 0 0
2 1 0 0 1 1 A,D,F

TA貢獻1820條經驗 獲得超10個贊
試試這個方法。
df = pd.DataFrame({"A":[0,0,1],"B":[1,0,0],"C":[0,0,0],"D":[1,0,1],"F":[1,0,1]})
df["new_column"] = df.apply(lambda x: (pd.DataFrame(x[x==1]).index.values),axis=1)
df["new_column"] = df["new_column"].apply(lambda x: ','.join(map(str, x)))
輸出
A B C D F new_column
0 0 1 0 1 1 B,D,F
1 0 0 0 0 0
2 1 0 0 1 1 A,D,F
添加回答
舉報