在pandas

时间:2018-05-30 14:52:45

标签: python pandas dataframe

列名称为: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

请在此帮助我,提前致谢

6 个答案:

答案 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.首先根据meltset_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 mask1转换为0 s 3。sort_values用于第一个解决方案 4.通过reset_indexNaN创建列 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()