当每个ID写下非零列名作为行时,需要将稀疏数据帧转换为形状。
我已经尝试过使用带循环的for循环-但是它非常慢,我不能使用它。 也许有人有更好的主意?
例如,初始df:
df=pd.DataFrame({'Id':['id1','id2','id3'], 'a':[0,1,1] ,'b':[1,0,1], 'c':[1,1,0]})
Id a b c
id1 0 1 1
id2 1 0 1
id3 1 1 0
预期:
Id columns
id1 b
id1 c
id2 a
id2 c
id3 a
id3 b
答案 0 :(得分:5)
使用熊猫.25.0
,这是使用.dot
和explode
的一种方式:
m=df.set_index('Id')
m.dot(m.columns+',').str[:-1].str.split(',').explode().reset_index(name='Columns')
Id Columns
0 0 b
1 0 c
2 1 a
3 1 c
4 2 a
5 2 b
答案 1 :(得分:3)
您似乎想要的只是堆积的索引,而不是值。我可以建议使用set_index
和stack
吗?
df2 = df.set_index('Id')
(df2[df2.astype(bool)]
.stack()
.index
.to_frame()
.reset_index(drop=True)
.set_axis(['Id', 'columns'], axis=1, inplace=False))
Id columns
0 0 b
1 0 c
2 1 a
3 1 c
4 2 a
5 2 b
答案 2 :(得分:3)
让我们使用melt
并用loc
进行过滤:
df.melt('Id').loc[lambda x: x['value'] != 0].sort_values('Id')
输出:
Id variable value
3 id1 b 1
6 id1 c 1
1 id2 a 1
7 id2 c 1
2 id3 a 1
5 id3 b 1
df.reset_index().melt(['index','Id']).loc[lambda x : x['value'] != 0].sort_values('index')
输出:
index Id variable value
3 0 id1 b 1
6 0 id1 c 1
1 1 id2 a 1
7 1 id2 c 1
2 2 id3 a 1
5 2 id3 b 1