【问题标题】:Convert one column to specific number of columns将一列转换为特定列数
【发布时间】:2020-01-06 15:55:04
【问题描述】:

我正在尝试根据其值将具有range(0,5) 值的一列数据转换为 6 列。 例如,如果它的值为 0,那么这六个中的第一列变为 1,其他变为 0,依此类推。但是,由于我的目标的形状是 (1034892, 1),它需要很多时间,甚至有时它会崩溃。这段代码适用于 500000 条数据,但对于这个数量却没有。

有没有办法让这么多的数据成为可能?

def convert_to_num_class(target):
    for i, value in enumerate(target):
        if i ==0:
            y_new =np.array( np.eye(6)[int(value[0])])
        else:
            y_new = np.vstack((y_new, np.eye(6)[int(value[0])]))
    return(y_new)

【问题讨论】:

  • 听起来像是 sklearn 的 One-Hot Encoder 的自制版本。使用内置有许多优化好处
  • @martineau 是的,这是可能的。非常感谢!

标签: python numpy bigdata


【解决方案1】:

使用熊猫get_dummies

>>> target = np.random.randint(6, size=(10, 1))  # the original target is of shape (1034892, 1)
>>> target = target.flatten()
array([0, 1, 0, 0, 4, 3, 1, 5, 4, 5])

>>> pd.get_dummies(target).to_numpy()
array([[1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 0, 0, 1, 0],
       [0, 0, 1, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 0, 0, 0, 1],
       [0, 0, 0, 1, 0],
       [0, 0, 0, 0, 1]])

如果您的目标没有您想要的范围内的所有值(如上面的示例,target 没有值 2),则该缺失值将缺少列。一种解决方法如下:

>>> target = pd.Categorical(target, categories=np.arange(6))

>>> pd.get_dummies(target).to_numpy()
array([[1, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1, 0],
       [0, 0, 0, 1, 0, 0],
       [0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 1]])

即使对于大小为(1034892, 1)target,它也非常快。

【讨论】:

  • 这是我在使用时遇到的错误。例外:数据必须是一维的。你有什么想法吗?
  • @pgol 我已经更新了我的答案。您只需将 target 展平(假设它是一个形状为 (1034892, 1) 的 numpy 数组)。
【解决方案2】:

我也通过使用 keras.utils.np_utils 的 to_categorical 解决了这个问题,这样的数据量只需要一秒钟:

from keras.utils.np_utils import to_categorical
def convert_to_num_class(target):
target = target.astype(np.int)
return(to_categorical(target, len(np.unique(target))))

【讨论】:

    【解决方案3】:

    无需使用pandaskeras,只需使用元组进行索引:

    import numpy as np
    
    categories = 6
    N = 10
    target = np.random.randint(categories, size=(N,1)) # this should be your data
    
    y = np.zeros((N, categories), dtype=np.uint8)
    mask = (np.arange(N), target.flatten())
    y[mask] = 1
    

    性能检查:

    def one_hot(target, categories=None): 
        target = target.flatten() 
        N = target.size 
        if categories is None:
            categories = target.max() - target.min() + 1 
        y = np.zeros((N, categories), dtype=np.uint8) 
        mask = (np.arange(N), target) 
        y[mask] = 1 
        return y 
    
    N = 1034892
    cats = 6
    r = np.random.randint(cats, size=(N))
    
    %timeit one_hot(r)
    # 9.63 ms ± 187 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    import pandas as pd
    %timeit pd.get_dummies(r).to_numpy()
    # 18.2 ms ± 183 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    【讨论】:

    • 我做到了,但处理这么多数据仍然需要很长时间。
    • 它在我的机器上基本上是即时的,有 1034892 个值。
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2022-12-09
    • 1970-01-01
    • 2021-03-18
    • 2021-05-11
    • 2018-03-19
    相关资源
    最近更新 更多