通过get\u dummies和pivot\u tab在融化后加入一个热编码

2024-10-03 19:32:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我有数据,我希望一个热编码后添加一些标签。下面的代码适用于玩具示例,是我在类似上下文中采用的方法。然而,它不可伸缩。例如,使用此数据帧:

import pandas as pd
import numpy as np

df = pd.DataFrame({'id' : [1, 2],
                   'C1' : ['X1', 'X2'],
                   'C2' : ['X2', np.NaN],
                   'C3' : ['X3', np.NaN],
                   'C4' : ['X4', 'X4']})

此时df由包含顺序无关紧要的字符串值的列组成。因此,一个立即数pd.get_dummies(df, prefix = '', prefix_sep = '', columns = ['C1', 'C2', 'C3', 'C4']将输出一个带有两个C2列的热编码数据帧,例如,这是不需要的。你知道吗

条目(id)可能有不同的长度(因此,np.NaN)。任何给定的id都不会包含重复的条目。但是,这些字符串值可能属于我希望添加标签的另一个类别。你知道吗

label_list = pd.DataFrame({'strval': ['X1','X2','X3','X4'],
                           'label' : [np.NaN, 'red', 'blue', 'red']})

然后我融化df并连接字符串vals,以便在适当的位置获得标签

dflong = pd.melt(df, id_vars = ['id'],
                 value_vars = ['C1', 'C2', 'C3', 'C4'],
                 value_name = 'strval')

dflab = dflong.merge(label_list, on = 'strval')

但是,在我的真实数据集中,100万行变成了2000万行。get\u dummies还可以在自己的行中分别对所有内容进行编码。我用pd.pivot_table将它塑造成适当的格式。你知道吗

dflab_gd = pd.get_dummies(dflab.drop(columns = ['variable']),
                          columns = ['strval', 'label'],
                          prefix = '', prefix_sep = '')

现在我想展平这个结果,以便每个id有一个条目。你知道吗

dflab_gd_flt = dflab_gd.pivot_table(index = ['id'], aggfunc = 'any', 
fill_value = 0).astype(int)

我喜欢这种方法,因为当我想通过更改aggfunc来计算符合同一标签的strval出现的次数时,我还可以将标签保留为计数。你知道吗

我的问题是:这种方法根本不能很好地扩展。有没有另一种方法来分配标签并获得一个热编码的数据帧(或一个热编码的标签的strvals和counts)更高效的计算?也许一个不涉及重塑长期结果融化?在将get_dummies应用到我的实际融化集之后,我得到了一个0/1的数据帧,它是2000万行乘30000列。你知道吗


Tags: 数据方法id编码dfgetprefixnp
1条回答
网友
1楼 · 发布于 2024-10-03 19:32:12

你不需要做一个热编码。如果你把“label”和“strval”放在同一列中,然后分组,你应该得到你需要的。你知道吗

df_concat = pd.concat(
    (dflab.drop(columns=['label']).rename({'strval': 'val'}, axis=1), 
     dflab.drop(columns=['strval']).rename({'label': 'val'}, axis=1)), 
    axis=0)

# use .any() or .count() as you would set aggfunc='any' or 'count'
dfg = df_concat.groupby(['id', 'val']).count()

# pivot to go from long to wide dataframe
dfg.reset_index().pivot('id', 'val').fillna(0).astype(int)

相关问题 更多 >