我的数据框看起来像这样:
我想将A:D范围内的所有1替换为列的名称,以便最终结果类似于:
我该怎么做?
您可以使用以下方法重新创建我的数据框:
dfz = pd.DataFrame({'A' : [1,0,0,1,0,0],
'B' : [1,0,0,1,0,1],
'C' : [1,0,0,1,3,1],
'D' : [1,0,0,1,0,0],
'E' : [22.0,15.0,None,10.,None,557.0]})
答案 0 :(得分:9)
一种方法是使用replace
并将系列映射列标签传递给值(在这种情况下是相同的标签):
>>> dfz.loc[:, 'A':'D'].replace(1, pd.Series(dfz.columns, dfz.columns))
A B C D
0 A B C D
1 0 0 0 0
2 0 0 0 0
3 A B C D
4 0 0 3 0
5 0 B C 0
要永久更改,您需要将返回的DataFrame分配回dfz.loc[:, 'A':'D']
。
除了解决方案之外,记住在列中混合数字和字符串类型时可能会失去很多性能优势很有用,因为pandas被迫使用泛型'对象&#39 ; dtype保存值。
答案 1 :(得分:2)
使用where
的解决方案:
>>> dfz.where(dfz != 1, dfz.columns.to_series(), axis=1)
A B C D E
0 A B C D 22.0
1 0 0 0 0 15.0
2 0 0 0 0 NaN
3 A B C D 10.0
4 0 0 3 0 NaN
5 0 B C 0 557.0
答案 2 :(得分:1)
我更喜欢来自@ajcr的非常优雅的解决方案。
如果您的列名不能轻易用于切片,这是我的解决方案:
dfz.ix[:, dfz.filter(regex=r'(A|B|C|D)').columns.tolist()] = (
dfz[dfz!=1].ix[:,dfz.filter(regex=r'(A|B|C|D)').columns.tolist()]
.apply(lambda x: x.fillna(x.name))
)
输出:
In [207]: dfz
Out[207]:
A B C D E
0 A B C D 22.0
1 0 0 0 0 15.0
2 0 0 0 0 NaN
3 A B C D 10.0
4 0 0 3 0 NaN
5 0 B C 0 557.0
答案 3 :(得分:1)
也许它不是那么优雅但是......只需循环遍历列并替换:
for i in dfz[['A','B','C','D']].columns:
dfz[i].replace(1,i,inplace=True)