2013-10-18 46 views
12

作为我正在研究的更广泛的程序的一部分,我最终将带有字符串,3D坐标等的对象数组混合在一起。我知道对象数组与结构化数组相比可能不是很受欢迎,但我希望能够在不改变大量代码的情况下解决这个问题。如何将对象dtype的Numpy 2D数组转换为常规的浮点数2D数组

让我们假设我的阵列obj_array的每一行(N行)具有

Single entry/object of obj_array: ['NAME',[10.0,20.0,30.0],....] 

格式现在,我试图加载这个对象数组和切片的三维坐标块。到此为止,一切正常,只需询问让我们说。

obj_array[:,[1,2,3]] 

但是结果也是一个对象数组,因为我想形成浮动的二维数组我将面对的问题:

size [N,3] of N rows and 3 entries of X,Y,Z coordinates 

现在,我遍历行和分配每将行排到目标2D浮点数组的一行以解决问题。我想知道是否有更好的方式与数组转换工具的numpy?我尝试了一些东西,无法绕过它。

Centers = np.zeros([N,3]) 

for row in range(obj_array.shape[0]): 
    Centers[row,:] = obj_array[row,1] 

感谢

+0

你能展示一个简单的示例代码 - 原始数据是什么样的,以及你的转换代码是什么样的?它会让别人更容易给你适当的建议。 – Floris

回答

8

讨厌的小问题...我一直与这个玩具例子鬼混:

>>> arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) 
>>> arr 
array([['one', [1, 2, 3]], 
     ['two', [4, 5, 6]]], dtype=object) 

我的第一个猜测是:

>>> np.array(arr[:, 1]) 
array([[1, 2, 3], [4, 5, 6]], dtype=object) 

但是,保持object dtype,所以也许那么:

>>> np.array(arr[:, 1], dtype=np.float) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: setting an array element with a sequence. 

可以正常工作解决此执行下列操作:

>>> np.array(arr[:, 1], dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: expected a readable buffer object 

不在这里,虽然,这是一种令人费解。显然,这是一个事实,即你的数组中的对象是列出了引发这一关,与元组替换表的工作原理:

>>> np.array([tuple(j) for j in arr[:, 1]], 
...   dtype=[('', np.float)]*3).view(np.float).reshape(-1, 3) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 

因为似乎没有被任何完全令人满意的解决方案,最简单的可能与去:

>>> np.array(list(arr[:, 1]), dtype=np.float) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 

虽然不会是非常有效的,可能是更好的东西,如去:

>>> np.fromiter((tuple(j) for j in arr[:, 1]), dtype=[('', np.float)]*3, 
...    count=len(arr)).view(np.float).reshape(-1, 3) 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 
1

您可能需要使用结构化ARR ay,这样当你需要独立地访问名称和值时,你可以轻松地进行操作。在这个例子中,有两个数据点:

x = zeros(2, dtype=[('name','S10'), ('value','f4',(3,))]) 
x[0][0]='item1' 
x[1][0]='item2' 
y1=x['name'] 
y2=x['value'] 

结果:

>>> y1 
array(['item1', 'item2'], 
     dtype='|S10') 
>>> y2 
array([[ 0., 0., 0.], 
     [ 0., 0., 0.]], dtype=float32) 

查看更多详细信息:http://docs.scipy.org/doc/numpy/user/basics.rec.html

3

基础上海梅玩具的例子,我认为你可以使用做到这一点很简单np.vstack()

arr = np.array([['one', [1, 2, 3]],['two', [4, 5, 6]]], dtype=np.object) 
float_arr = np.vstack(arr[:, 1]).astype(np.float) 

这将w ork,而不管对象数组中的“数字”元素是否为一维numpy数组,列表或元组。

1

这工作很好,你的数组arr将从一个对象转换为一个浮点数组。数字处理非常简单。感谢那最后一篇文章!我只是修改了它包括任何数据帧大小:

float_arr = np.vstack(arr[:, :]).astype(np.float) 
+0

这是一个比答案更多的评论。它与ali_m的答案有关吗? – jogo

0

这是方式更快地只是你的对象数组转换为NumPy的float数组: arr=np.array(arr, dtype=[('O', np.float)]).astype(np.float) - 从那里没有循环,指数它就像你通常会怎么做在一个NumPy数组上。尽管数据类型不同,但您必须使用不同的数据类型arr[:, 1],arr[:,2]等。如果与从C++ DLL函数返回的NumPy元组对象发生同样的问题 - 17M元素的转换需要< 2秒。

+0

如果有人真正尝试过上述解决方案并对其进行配置,它不会被低估。 – Matt

0

这个问题通常发生在您使用不同类型的数据集时,通常是第一列左右的日期。

我用来做的是将日期列存储在一个不同的变量;并将剩余的“X特征矩阵”转换为X.因此,例如,我有日期和X.

然后我申请转换为X矩阵为:

X = np.array(list(X[:,:]), dtype=np.float)

希望能帮到!