我有一个带布尔值的df(整数值可以是0或1,但是现在不重要):
A B C D
0 0 1 0
1 0 0 0
0 1 1 1
1 0 0 1
我想对其进行转换,以便将“ 1”(真)值转换为该列的标题名称,将0值转换为NaN。生成的df不需要标题。 预期输出:
NaN NaN C NaN
A NaN NaN NaN
NaN B C D
A NaN NaN D
遍历行并通过检查分配这些值可能有效,但是没有更快/更通用的熊猫方式吗?
答案 0 :(得分:2)
在numpy中
np.where(df == 1, df.columns, np.nan)
array([[nan, nan, 'C', nan],
['A', nan, nan, nan],
[nan, 'B', 'C', 'D'],
['A', nan, nan, 'D']], dtype=object)
如何将np.array转换为pd.DataFrame(由@jezrael添加)
df = pd.DataFrame(np.where(df == 1, df.columns, np.nan), columns=df.columns)
print (df)
A B C D
0 NaN NaN C NaN
1 A NaN NaN NaN
2 NaN B C D
3 A NaN NaN D
答案 1 :(得分:2)
也许是DataFrame.apply的东西:
df.apply(lambda s: [s.name if v == 1 else np.nan for v in s])
答案 2 :(得分:1)
您可以使用此:
for i in df.columns:
df[i] = df[i].apply(lambda x: i if x==1 else np.nan)
df.columns = [''] * len(df.columns)
答案 3 :(得分:1)
您可以使用如下所示的np.where或pd.mask
np.where(df.values==1, df.columns, np.nan)
## or
df.mask(df==1,df.columns)
答案 4 :(得分:1)
如果性能很重要,则将numpy.where
与DataFrame
构造函数一起使用,并且不使用column参数:
df = pd.DataFrame(np.where(df == 1, df.columns, np.nan))
print (df)
0 1 2 3
0 NaN NaN C NaN
1 A NaN NaN NaN
2 NaN B C D
3 A NaN NaN D
如果需要在无列和索引值的文件中输出,请在DataFrame.to_csv
上添加index=False
和header=None
:
df.to_csv('file.csv', index=False, header=None)
编辑:
如果性能很重要,则可以避免使用apply
,因为它会在引擎盖下循环。对于矢量化最快,最快的解决方案,最好使用np.where
:
#[40000 rows x 40 columns]
df = pd.concat([df] * 10000, ignore_index=True)
df = pd.concat([df] * 10, ignore_index=True, axis=1)
In [180]: %%timeit
...: for i in df.columns:
...: df[i] = df[i].apply(lambda x: i if x==1 else np.nan)
...:
690 ms ± 13.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [181]: %%timeit
...: df.apply(lambda s: [s.name if v == 1 else np.nan for v in s])
...:
680 ms ± 23 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [182]: %%timeit
...: pd.DataFrame(np.where(df == 1, df.columns, np.nan))
...:
42.7 ms ± 3.26 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [183]: %%timeit
...: df.T.where(df.T != 1, df.columns).T.where(df != 0, np.nan)
...:
17 s ± 644 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
答案 5 :(得分:0)
您还可以使用where
中的pandas
:
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.where.html)
请注意,T
对于获得适当的结果很重要。
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': [0,1,0,1],
'B': [0,0,1,0],
'C': [1,0,1,0],
'D': [0,0,1,1]
})
df = df.T.where(df.T != 1, df.columns).T.where(df != 0, np.nan)
输出:
A B C D
0 NaN NaN C NaN
1 A NaN NaN NaN
2 NaN B C D
3 A NaN NaN D