我有这个数组
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]))
但是我想知道是否有更好的扩展,因为我想将它应用于具有几百万个数据点的数组。
答案 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循环。