2012-08-31 38 views
0

我试图使用ufunc将一个N * 1 numpy数组整数有效地映射到N * 3 numpy浮点数组。使用ufunc映射numpy数组

我有什么至今:

map = {1: (0, 0, 0), 2: (0.5, 0.5, 0.5), 3: (1, 1, 1)} 
ufunc = numpy.frompyfunc(lambda x: numpy.array(map[x], numpy.float32), 1, 1) 

input = numpy.array([1, 2, 3], numpy.int32) 

ufunc(input)给出了一个3×3阵列D型对象。我想这个数组,但与D型float32。

+2

'map'和'input'是Python内置函数。最好不要为这些名称分配新的值,因为它使得很难访问Python内置函数。 – unutbu

+0

'frompyfunc'的文档说“返回的ufunc总是返回PyObject数组”。无论这个原因是什么,有一个相当简单的解决方法:提交一个适当的输入类型的输出矩阵作为“out”参数。 – Alexey

回答

1

你可以使用np.hstack

import numpy as np 
mapping = {1: (0, 0, 0), 2: (0.5, 0.5, 0.5), 3: (1, 1, 1)} 
ufunc = np.frompyfunc(lambda x: np.array(mapping[x], np.float32), 1, 1, dtype = np.float32) 

data = np.array([1, 2, 3], np.int32) 
result = np.hstack(ufunc(data)) 
print(result) 
# [ 0. 0. 0. 0.5 0.5 0.5 1. 1. 1. ] 
print(result.dtype) 
# float32 
print(result.shape) 
# (9,) 
1

您可以使用ndarray看中指数得到相同的结果,我认为它应该比frompyfunc快:

map_array = np.array([[0,0,0],[0,0,0],[0.5,0.5,0.5],[1,1,1]], dtype=np.float32) 
index = np.array([1,2,3,1]) 
map_array[index] 

或者你也可以使用列表理解:

map = {1: (0, 0, 0), 2: (0.5, 0.5, 0.5), 3: (1, 1, 1)} 
np.array([map[i] for i in [1,2,3,1]], dtype=np.float32)  
+0

输入列表非常大,所以我试图避免创建中间列表或数组。 –

1

如果你的映射是一个numpy数组,你可以使用花式索引g下这样的​​:

>>> valmap = numpy.array([(0, 0, 0), (0.5, 0.5, 0.5), (1, 1, 1)]) 
>>> input = numpy.array([1, 2, 3], numpy.int32) 
>>> valmap[input-1] 
array([[ 0. , 0. , 0. ], 
     [ 0.5, 0.5, 0.5], 
     [ 1. , 1. , 1. ]]) 
1

除非我误读了文档的np.frompyfunc上一个标量输出对象确实是:使用ndarray作为输入时,你会得到一个ndarraydtype=obj

一种解决方法是使用np.vectorize功能:

F = np.vectorize(lambda x: mapper.get(x), 'fff') 

在这里,我们迫使F的输出的dtype为3个浮子(因此'fff')。

>>> mapper = {1: (0, 0, 0), 2: (0.5, 1.0, 0.5), 3: (1, 2, 1)} 
>>> inp = [1, 2, 3] 
>>> F(inp) 
(array([ 0. , 0.5, 1. ], dtype=float32), array([ 0., 0.5, 1.], dtype=float32), array([ 0. , 0.5, 1. ], dtype=float32)) 

OK,并不完全符合我们想:这是三个浮点阵列的元组(因为我们送“FFF”),第一阵列等价于[mapper[i][0] for i in inp]。因此,通过一些操作:

>>> np.array(F(inp)).T 
array([[ 0. , 0. , 0. ], 
     [ 0.5, 0.5, 0.5], 
     [ 1. , 1. , 1. ]], dtype=float32)