列名称为:ID,1,2,3,4,5,6,7,8,9。
col值为0或1
我的数据框如下所示:
ID 1 2 3 4 5 6 7 8 9
1002 0 1 0 1 0 0 0 0 0
1003 0 0 0 0 0 0 0 0 0
1004 1 1 0 0 0 0 0 0 0
1005 0 0 0 0 1 0 0 0 0
1006 0 0 0 0 0 1 0 0 0
1007 1 0 1 0 0 0 0 0 0
1000 0 0 0 0 0 0 0 0 0
1009 0 0 1 0 0 0 1 0 0
我希望列前面的列名称中行的值为1。
我想要的Dataframe应该是这样的:
ID Col2
1002 2 // has 1 at Col(2) and Col(4)
1002 4
1004 1 // has 1 at col(1) and col(2)
1004 2
1005 5 // has 1 at col(5)
1006 6 // has 1 at col(6)
1007 1 // has 1 at col(1) and col(3)
1007 3
1009 3 // has 1 at col(3) and col(7)
1009 7
请在此帮助我,提前致谢
答案 0 :(得分:4)
set_index
+ stack
,堆栈默认为dropna
df.set_index('ID',inplace=True)
df[df==1].stack().reset_index().drop(0,1)
Out[363]:
ID level_1
0 1002 2
1 1002 4
2 1004 1
3 1004 2
4 1005 5
5 1006 6
6 1007 1
7 1007 3
8 1009 3
9 1009 7
答案 1 :(得分:4)
您可以在列上使用idxmax来反转pd.get_dummies,例如
one_hot_encoded = pd.get_dummies(original)
original_back = one_hot_encoded.idxmax(axis=1)
答案 2 :(得分:4)
关于OP帖子的几个很好的答案。但是,get_dummies
通常用于多个分类特征。 Pandas使用前缀分隔符prefix_sep
来区分列的不同值。
以下函数折叠“虚拟化”数据框,同时保持列的顺序:
def undummify(df, prefix_sep="_"):
cols2collapse = {
item.split(prefix_sep)[0]: (prefix_sep in item) for item in df.columns
}
series_list = []
for col, needs_to_collapse in cols2collapse.items():
if needs_to_collapse:
undummified = (
df.filter(like=col)
.idxmax(axis=1)
.apply(lambda x: x.split(prefix_sep, maxsplit=1)[1])
.rename(col)
)
series_list.append(undummified)
else:
series_list.append(df[col])
undummified_df = pd.concat(series_list, axis=1)
return undummified_df
>>> df
a b c
0 A_1 B_1 C_1
1 A_2 B_2 C_2
>>> df2 = pd.get_dummies(df)
>>> df2
a_A_1 a_A_2 b_B_1 b_B_2 c_C_1 c_C_2
0 1 0 1 0 1 0
1 0 1 0 1 0 1
>>> df3 = undummify(df2)
>>> df3
a b c
0 A_1 B_1 C_1
1 A_2 B_2 C_2
答案 3 :(得分:3)
使用:
[9, 18, 99, 7, 4, 21, [3, 5, [27, 57, 92], 7, 76], 32, 4]
99
[2, 9, [1, 13], 8, 6]
13
[2, [[100, 7], 90], [1, 13], 8, 6]
100
[[[13, 7], 90], 2, [1, 100], 8, 6]
100
[[[-13, -7], -90], -2, [-1, -100], -8, -6]
-1
['abc', 'd', ['ef', 'ghi', ['jkl', 'zzz'], 'xy', 'z']]
zzz
替代解决方案:
df = (df.melt('ID', var_name='Col2')
.query('value== 1')
.sort_values(['ID', 'Col2'])
.drop('value',1))
df = (df.set_index('ID')
.mask(lambda x: x == 0)
.stack()
.reset_index()
.drop(0,1))
<强>解释强>:
1.首先根据melt
或set_index
重塑unstack
的值
2.仅按query
过滤print (df)
ID Col2
8 1002 2
24 1002 4
2 1004 1
10 1004 2
35 1005 5
44 1006 6
5 1007 1
21 1007 3
23 1009 3
55 1009 7
或mask
将1
转换为0
s
3。sort_values
用于第一个解决方案
4.通过reset_index
从NaN
创建列
5.最后按MultiIndex
答案 4 :(得分:3)
np.argwhere
v = np.argwhere(df.drop('ID', 1).values).T
pd.DataFrame({'ID' : df.loc[v[0], 'ID'], 'Col2' : df.columns[1:][v[1]]})
Col2 ID
0 2 1002
0 4 1002
2 1 1004
2 2 1004
3 5 1005
4 6 1006
5 1 1007
5 3 1007
7 3 1009
7 7 1009
argwhere
获取DataFrame中所有非零元素的i,j索引。使用第一列索引索引到列ID
,使用第二列索引索引到df.columns
。
我在步骤2之前转换v
以提高缓存效率,减少输入。
答案 5 :(得分:0)
https://stackoverflow.com/a/55757342/2384397
在这里重写: 将dat [“ classification”]转换为一种热编码并返回!
将熊猫作为pd导入
从sklearn.preprocessing导入LabelEncoder
dat [“ labels”] = le.fit_transform(dat [“ classification”])
Y = pd.get_dummies(dat [“ labels”])
tru = []
对于范围在(0,len(Y))中的i: tru.append(np.argmax(Y.iloc [i]))
tru = le.inverse_transform(tru)
完全相同! (tru == dat [“ classification”])。value_counts()