Python 将分类数据转换为虚拟集

Python 将分类数据转换为虚拟集,python,pandas,scikit-learn,dummy-variable,Python,Pandas,Scikit Learn,Dummy Variable,我有这样的数据:- |--------|---------| | Col1 | Col2 | |--------|---------| | X | a,b,c | |--------|---------| | Y | a,b | |--------|---------| | X | b,d | |--------|---------| |------|------|------|------|------|------| |Col_X

我有这样的数据:-

|--------|---------|
| Col1   | Col2    |
|--------|---------|
| X      | a,b,c   |
|--------|---------|
| Y      | a,b     |
|--------|---------|
| X      | b,d     |
|--------|---------|
|------|------|------|------|------|------|
|Col_X |Col_Y |Col2_a|Col2_b|Col2_c|Col2_d|
|------|------|------|------|------|------|
|  1   |  0   |  1   |  1   |  1   |  0   |
|------|------|------|------|------|------|
|  0   | 1    |  1   |  1   |  0   |   0  |
|------|------|------|------|------|------|
|  1   | 0    |  0   |  1   |  0   |   1  |
|------|------|------|------|------|------|
我想把这些分类数据转换成虚拟变量。由于我的数据很大,如果我使用pandas的
get_dummies()
,则会出现内存错误。我希望我的结果如下:-

|--------|---------|
| Col1   | Col2    |
|--------|---------|
| X      | a,b,c   |
|--------|---------|
| Y      | a,b     |
|--------|---------|
| X      | b,d     |
|--------|---------|
|------|------|------|------|------|------|
|Col_X |Col_Y |Col2_a|Col2_b|Col2_c|Col2_d|
|------|------|------|------|------|------|
|  1   |  0   |  1   |  1   |  1   |  0   |
|------|------|------|------|------|------|
|  0   | 1    |  1   |  1   |  0   |   0  |
|------|------|------|------|------|------|
|  1   | 0    |  0   |  1   |  0   |   1  |
|------|------|------|------|------|------|
我曾尝试使用MemoryError转换Col2,但由于数据量大,而且Col2中也存在很多变化,因此获取MemoryError是非常困难的

所以

1) 如何将多个分类列转换为伪变量


2) pandas get_dummy()给出了内存错误,那么我如何处理它呢?

我几乎可以肯定,您遇到了内存问题,因为返回的数组中满是1和0,数据类型为
np.int64
。这与的行为截然不同,后者返回一个数据类型为
uint8
的值数组

这似乎是一个错误。然而,在过去的一年里,没有更新,也没有修复。签出for str.get_假人确实会确认它返回了
np.int64

8位整数将占用1字节内存,而64位整数将占用8字节内存。我希望通过找到一种替代热编码
Col2
的方法来避免内存问题,这种方法可以确保输出都是8位整数

以下是我的方法,从你的例子开始:

df = pd.DataFrame({'Col1': ['X', 'Y', 'X'],
                   'Col2': ['a,b,c', 'a,b', 'b,d']})
df

    Col1    Col2
0   X       a,b,c
1   Y       a,b
2   X       b,d
  • 由于
    Col1
    包含简单的非分隔字符串,因此我们可以使用pd.get\u假人轻松对其进行热编码:
  • 到目前为止还不错

    df['Col1_X'].values.dtype
    dtype('uint8')
    
  • 让我们获得
    Col2
    中逗号分隔字符串中包含的所有唯一子字符串的列表:
  • 现在我们可以循环浏览上面的值列表,并使用
    str.contains
    为每个值创建一个新列,例如
    'a'
    。如果新列中的每一行在
    Col2
    中的字符串中实际具有新列的值,例如
    'a'
    ,则该行将包含1。在创建每个新列时,我们确保将其数据类型转换为
    uint8
  • 这将生成符合所需格式的数据帧。谢天谢地,从
    Col2
    热编码的四个新列中的整数每个只占1字节,而不是8字节

    df['Col2_a'].dtype
    dtype('uint8')
    

    如果有机会,上述方法不起作用。我的建议是使用str.get_dummies将一个热编码
    Col2
    分为几行。每次执行块时,您都会将其数据类型从
    np.int64
    转换为
    uint8
    ,然后。您最终可以将所有块重新连接在一起。

    我也想给出我的解决方案。我要感谢@James dellinger的回答。这就是我的方法

    df = pd.DataFrame({'Col1': ['X', 'Y', 'X'],
                   'Col2': ['a,b,c', 'a,b', 'b,d']})
    df
    
      Col1  Col2
    0   X   a,b,c
    1   Y   a,b
    2   X   b,d
    
    我首先拆分Col2值并将其转换为列值

    df= pd.DataFrame(df['Col2'].str.split(',',3).tolist(),columns = ['Col1','Col2','Col3'])
    
    df
    
       Col1 Col2 Col3
    0   a   b    c
    1   a   b    None
    2   b   d    None
    
    然后我在这个数据帧上应用了虚拟创建,没有给出任何前缀

    df=pd.get_dummies(df, prefix="")
    
    df
    
        _a  _b  _b  _d  _c
    0   1   0   1   0   1
    1   1   0   1   0   0
    2   0   1   0   1   0
    
    现在,为了得到所需的结果,我们可以将所有重复的列相加

    df.groupby(level=0, axis=1).sum()
    
    df
    
        _a  _b  _c  _d
    0   1   1   1   0
    1   1   1   0   0
    2   0   1   0   1
    

    对于Col1,我们可以使用
    pd.get\u dummies()
    直接创建虚拟变量,并将其存储到不同的数据帧中,假设
    Col1\u df
    。我们可以使用
    pd.concat([df,col1_-df],axis=1,sort=False)对两列进行concat。

    您可以先对数据进行预处理。如果您正在处理ML,则可以删除stopwords并应用词干分析和柠檬化,这将减少数据中唯一单词的数量。是的,我需要将此数据用于ML,但我不处理文本数据。这是str.@Vaishaliit中的一些代码,暂时没有给出内存错误。但这一过程持续了相当长的时间。我们可以做任何事情来加速这个过程。而且它的给定
    不能将float NaN转换为整数
    ,因为一些行也包含空值。对于
    Col2
    ,只需使用这个:df['Col2'].str.get_dummies(sep=','),我喜欢这种方法。我最初尝试过类似的方法,但我没有想到可以将前缀留空,然后用相同的后缀对列进行分组。我还想知道,如果我使用此数据集部署模型,如何将其应用于实时输入@jamesdelfinlli假设您将在预处理管道中包含上述步骤,并且在对任何新输入进行预测之前,都将对其进行相应的预处理。
    df.groupby(level=0, axis=1).sum()
    
    df
    
        _a  _b  _c  _d
    0   1   1   1   0
    1   1   1   0   0
    2   0   1   0   1