Используйте numpy.where
с конструктором DataFrame
и параметром без столбцов, если производительность важна:
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
И при необходимости выведите файл без столбцов и значений индекса, добавьте index=False
и header=None
до DataFrame.to_csv
:
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)