python Pandas中的“one-hot”反向编码

kmbjn2e3  于 2023-01-16  发布在  Python
关注(0)|答案(9)|浏览(348)

我想从这个 Dataframe 开始,它基本上是一个热编码。

In [2]: pd.DataFrame({"monkey":[0,1,0],"rabbit":[1,0,0],"fox":[0,0,1]})

    Out[2]:
       fox  monkey  rabbit
    0    0       0       1
    1    0       1       0
    2    1       0       0
    3    0       0       0
    4    0       0       0

到这个是“反向”独热编码的。

In [3]: pd.DataFrame({"animal":["monkey","rabbit","fox"]})
    Out[3]:
       animal
    0  monkey
    1  rabbit
    2     fox

我想有一些聪明的使用apply或zip来做事情,但我不知道怎么做...有人能帮忙吗?
我还没有太多的成功使用索引等试图解决这个问题。

xienkqul

xienkqul1#

    • 更新:**我认为ayhan是正确的,它应该是:
df.idxmax(axis=1)

这将为每一行选择一个列标签,其中标签具有最大值。由于数据是1和0,它将选择1的位置。
演示:

In [40]: s = pd.Series(['dog', 'cat', 'dog', 'bird', 'fox', 'dog'])

In [41]: s
Out[41]:
0     dog
1     cat
2     dog
3    bird
4     fox
5     dog
dtype: object

In [42]: pd.get_dummies(s)
Out[42]:
   bird  cat  dog  fox
0   0.0  0.0  1.0  0.0
1   0.0  1.0  0.0  0.0
2   0.0  0.0  1.0  0.0
3   1.0  0.0  0.0  0.0
4   0.0  0.0  0.0  1.0
5   0.0  0.0  1.0  0.0

In [43]: pd.get_dummies(s).idxmax(1)
Out[43]:
0     dog
1     cat
2     dog
3    bird
4     fox
5     dog
dtype: object
    • 旧答案:**(很可能是错误答案)

试试这个:

In [504]: df.idxmax().reset_index().rename(columns={'index':'animal', 0:'idx'})
Out[504]:
   animal  idx
0     fox    2
1  monkey    1
2  rabbit    0

数据:

In [505]: df
Out[505]:
   fox  monkey  rabbit
0    0       0       1
1    0       1       0
2    1       0       0
3    0       0       0
4    0       0       0
9gm1akwq

9gm1akwq2#

我将使用apply来解码列:

In [2]: animals = pd.DataFrame({"monkey":[0,1,0,0,0],"rabbit":[1,0,0,0,0],"fox":[0,0,1,0,0]})

In [3]: def get_animal(row):
   ...:     for c in animals.columns:
   ...:         if row[c]==1:
   ...:             return c

In [4]: animals.apply(get_animal, axis=1)
Out[4]: 
0    rabbit
1    monkey
2       fox
3      None
4      None
dtype: object
2uluyalo

2uluyalo3#

这适用于单个标签和多个标签。
我们可以使用高级索引来解决这个问题。这里是链接。

import pandas as pd

df = pd.DataFrame({"monkey":[1,1,0,1,0],"rabbit":[1,1,1,1,0],\
    "fox":[1,0,1,0,0], "cat":[0,0,0,0,1]})

df['tags']='' # to create an empty column

for col_name in df.columns:
    df.ix[df[col_name]==1,'tags']= df['tags']+' '+col_name

print df

结果是:

cat  fox  monkey  rabbit                tags
0    0    1       1       1   fox monkey rabbit
1    0    0       1       1       monkey rabbit
2    0    1       0       1          fox rabbit
3    0    0       1       1       monkey rabbit
4    1    0       0       0                 cat

说明:我们迭代 Dataframe 上的列。

df.ix[selection criteria, columns to write value] = value
df.ix[df[col_name]==1,'tags']= df['tags']+' '+col_name

上面的代码行基本上可以找到df[col_name] == 1的所有位置,选择列“tags”并将其设置为RHS值,即df ['tags']+' '+ col_name

注意:.ix自Pandas v0.20起已弃用。您应根据需要改用.loc.iloc

hfsqlsce

hfsqlsce4#

我会这样做:

cols = df.columns.to_series().values
pd.DataFrame(np.repeat(cols[None, :], len(df), 0)[df.astype(bool).values], df.index[df.any(1)])

时间

  • MaxU的方法在大型 Dataframe 方面具有优势 *
    小号x1毫米1x 5 x 3

大号x 1米1英寸x 100万x 52英寸

wi3ka0sx

wi3ka0sx5#

您可以尝试使用melt()。当一行有多个OHE标签时,此方法也有效。

# Your OHE dataframe 
df = pd.DataFrame({"monkey":[0,1,0],"rabbit":[1,0,0],"fox":[0,0,1]})

mel = df.melt(var_name=['animal'], value_name='value') # Melting

mel[mel.value == 1].reset_index(drop=True) # this gives you the result
dojqjjoe

dojqjjoe6#

从panda 1.5.0开始,pandas.from_dummies直接支持反转独热码编码:

import pandas as pd  # v 1.5.0

onehot_df = pd.DataFrame({
    "monkey": [0, 1, 0],
    "rabbit": [1, 0, 0],
    "fox": [0, 0, 1]
})

new_df = pd.from_dummies(onehot_df)

#          
# 0  rabbit
# 1  monkey
# 2     fox

生成的DataFrame似乎没有列标题(它是一个空字符串)。要解决此问题,请对from_dummies之后的列执行rename操作

new_df = pd.from_dummies(onehot_df).rename(columns={'': 'animal'})

#    animal
# 0  rabbit
# 1  monkey
# 2     fox

或者,如果DataFrame已定义为具有单独的列(如pandas.get_dummies生成的one-hot编码),* 例如 *

import pandas as pd  # v 1.5.0

onehot_df = pd.DataFrame({
    'animal_fox': [0, 0, 1],
    'animal_monkey': [0, 1, 0],
    'animal_rabbit': [1, 0, 0]
})

#    animal_fox  animal_monkey  animal_rabbit
# 0           0              0              1
# 1           0              1              0
# 2           1              0              0

只需指定sep即可反转编码

new_df = pd.from_dummies(onehot_df, sep='_')

#    animal
# 0  rabbit
# 1  monkey
# 2     fox

sep分隔符的第一个示例之前的字符串将成为新DataFrame中的列标题(在本例中为“animal”),字符串的其余部分将成为列值(在本例中为“rabbit”、“monkey”、“fox”)。

m2xkgtsf

m2xkgtsf7#

试试这个:

df = pd.DataFrame({"monkey":[0,1,0,1,0],"rabbit":[1,0,0,0,0],"fox":[0,0,1,0,0], "cat":[0,0,0,0,1]})
df 

   cat  fox  monkey  rabbit
0    0    0       0       1
1    0    0       1       0
2    0    1       0       0
3    0    0       1       0
4    1    0       0       0

pd.DataFrame([x for x in np.where(df ==1, df.columns,'').flatten().tolist() if len(x) >0],columns= (["animal"]) )

   animal
0  rabbit
1  monkey
2     fox
3  monkey
4     cat
42fyovps

42fyovps8#

它可以通过简单的 Dataframe 应用程序来实现

# function to get column name with value one for each row in dataframe
def get_animal(row):
    return(row.index[row.apply(lambda x: x==1)][0])

# prepare a animal column
df['animal'] = df.apply(lambda row:get_animal(row), axis=1)
moiiocjp

moiiocjp9#

一种不用for循环就可以处理多个标签的方法。结果将是一个列表列。如果每行的标签数相同,则可以添加result_type='expand'以获得多个列。

df.apply(lambda x: df.columns[x==1], axis=1)

相关问题