如何将标题映射到pandas中的列?

sun*_*nny 12 python pandas

我有一个数据帧,如:

A    B    C 
1    0    0
1    1    0
0    1    0
0    0    1
Run Code Online (Sandbox Code Playgroud)

我希望有 :

 A    B    C  label
 1    0    0   A
 1    1    0   AB
 0    1    0   B
 0    0    1   C
Run Code Online (Sandbox Code Playgroud)

我试图通过地图或申请,但我无法弄明白.

Ted*_*rou 21

这是一个惯用且高效的解决方案

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
Run Code Online (Sandbox Code Playgroud)

  • 这很优雅! (2认同)

piR*_*red 13

运用 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
Run Code Online (Sandbox Code Playgroud)

使用底层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
Run Code Online (Sandbox Code Playgroud)


Max*_*axU 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
Run Code Online (Sandbox Code Playgroud)

PS我绝对会选择@Ted的解决方案,因为它更好,更快......更快

  • "在[101]中:"我想知道那台笔记本上还有什么 (3认同)

WeN*_*Ben 6

或使用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
Run Code Online (Sandbox Code Playgroud)

要么

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
Run Code Online (Sandbox Code Playgroud)

  • @sunny你可以提出这些答案,请接受泰德的回答 (3认同)
  • 你们比我更善良.我必须软化我的灵魂. (3认同)
  • @TedPetrou对我来说,声誉远远不如学习一个好的解决方案!!!!,你的答案是我的一天,我正在努力将我的一些工作代码替换为你的解决方案:),祝你有愉快的一天! (3认同)

Ale*_*der 5

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
Run Code Online (Sandbox Code Playgroud)

时机

# 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
Run Code Online (Sandbox Code Playgroud)