将数组转换为序数回归编码的有效方法

时间:2018-03-29 08:25:51

标签: python arrays numpy

我有这个数组

import numpy as np
array = np.array([2, 3, 4])

我想把它映射到

[array([ 1.,  1.,  0.,  0.,  0.]), array([ 1.,  1.,  1.,  0.,  0.]), array([ 1.,  1.,  1.,  1.,  0.])]

这是我迄今为止找到的最佳解决方案

def ordinal_array(where_max, array_len=5):
    return np.hstack((np.ones((where_max)), np.zeros((array_len-where_max))))

list(map(ordinal_array,[2,3,4]))

但是我想知道是否有更好的扩展,因为我想将它应用于具有几百万个数据点的数组。

2 个答案:

答案 0 :(得分:4)

outer-comparison值的范围内使用大于array_len输入数组的broadcasting -

In [14]: array
Out[14]: array([2, 3, 4])

In [15]: array_len = 5

In [16]: (array[:,None] > np.arange(array_len)).astype(float)
Out[16]: 
array([[1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0.],
       [1., 1., 1., 1., 0.]])

内置NumPy -

In [23]: np.greater.outer(array, np.arange(array_len)).astype(float)
Out[23]: 
array([[1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0.],
       [1., 1., 1., 1., 0.]])

为了提高性能,请考虑转换为较低精度int或甚至将输出保持为布尔数组(为此跳过astype转换)。

答案 1 :(得分:0)

我认为在开始时创建整个矩阵可以使它更快。请看下面的f2函数。

import random
import numpy as np

def ordinal_array(where_max, array_len=5):
    return np.hstack((np.ones((where_max)), np.zeros((array_len-where_max))))

def f1(arr):
  return list(map(ordinal_array,arr))

def f2(arr):
  n = len(arr)
  retval = np.zeros((n, 5))
  for i in range(n):
    no = arr[i]
    retval[i, 0:no] = 1
  return list(retval)

a = [random.randint(0, 5) for i in range(100000)]

%timeit f1(a)
%timeit f2(a)

对于100000件物品似乎更快。

  

1个循环,最佳3:每循环816毫秒

     

10个循环,最佳3:每循环95.7 ms

甚至可以减少f2函数中的for循环。