布尔值到一个列表中的列名,dataframe pandas python

amn*_*n89 4 python list dataframe pandas

我有这样的数据帧

     A    B    C    D    E
  0  0.0  1.0  0.0  0.0  1.0
  1  0.0  0.0  1.0  0.0  0.0
  2  0.0  1.0  1.0  1.0  0.0
  3  1.0  0.0  0.0  0.0  1.0
  4  0.0  0.0  0.0  1.0  0.0
Run Code Online (Sandbox Code Playgroud)

任务是获得这样的列表

0  B,E
1  C
2  B,C,D
3  A,E
4  D
Run Code Online (Sandbox Code Playgroud)

任何想法,提前谢谢.

jez*_*ael 5

您可以使用applywith axis=1进行按行处理,然后将每一行与1索引值进行比较(因为axis=1每一行都转换为带有索引的系列),它们通过,以下方式连接:

s1 = df.apply(lambda x: ','.join(x.index[x == 1]), axis=1)
print (s1)
0      B,E
1        C
2    B,C,D
3      A,E
4        D
dtype: object
Run Code Online (Sandbox Code Playgroud)

另一种解决方案,更快,如果较大DataFrame.

首先更改要列出的列的格式:

print (['{}, '.format(x) for x in df.columns])
['A, ', 'B, ', 'C, ', 'D, ', 'E, ']
Run Code Online (Sandbox Code Playgroud)

相似:

s = np.where(df == 1, ['{}, '.format(x) for x in df.columns], '')
Run Code Online (Sandbox Code Playgroud)

因为1值被转换为Trues.比较DataFrameTrue使用列名的自定义格式的值和:

s = np.where(df, ['{}, '.format(x) for x in df.columns], '')
print (s)
[['' 'B, ' '' '' 'E, ']
 ['' '' 'C, ' '' '']
 ['' 'B, ' 'C, ' 'D, ' '']
 ['A, ' '' '' '' 'E, ']
 ['' '' '' 'D, ' '']]
Run Code Online (Sandbox Code Playgroud)

最后使用删除空值连接所有行:

s1 = pd.Series([''.join(x).strip(', ') for x in s], index=df.index)
print (s1)
0       B, E
1          C
2    B, C, D
3       A, E
4          D
dtype: object
Run Code Online (Sandbox Code Playgroud)