Python将记录添加到数组中

时间:2012-10-12 09:25:13

标签: python arrays numpy

我有一个定义为 -

的数组
import numpy as np
A = np.recarray((3,),dtype=[('x',float), ('y', float), ('z',float)])

另一个阵列B,从CSV文件中读取为 -

>>> print B
[(7.0, 0.0, 7.0) (16.0, 0.0, 1.0)]

当我尝试将元素添加到数组时,如下所示 -

for i in range(B.size):
    if(B[i][0] != 0.):
        A.append((0.,B[i][1],B[i][2]))
    if(B[i][1] != 0.):
        A.append((B[i][0],0.,B[i][2]))
    if(B[i][2] != 0.):
        A.append((B[i][0],B[i][1],0.))

我收到如下错误 -

File "/usr/lib/python2.7/dist-packages/numpy/core/records.py", line 416, in __getattribute__
    raise AttributeError, "record array has no attribute %s" % attr
    AttributeError: record array has no attribute append

我无法理解这个字符串属性(%s)在哪里出现?

有人可以帮忙吗?

更新 我将代码更改为np.append(A,(0.,B[i][1],B[i][2])),但我收到另一个错误 - TypeError: invalid type promotion

2 个答案:

答案 0 :(得分:1)

错误只是说recarray没有任何名为append的方法。

我还没有真正使用numpy但是一个解决方案可能是将A转换为列表

A.tolist()

将记录附加到此列表,然后执行类似

的操作
np.fromiter(x, A.dtype)

获得新的重新组合。当然,这看起来不是一个好的解决方案。

也许更熟悉numpy的人可以投入并改进它。

答案 1 :(得分:1)

附加到numpy数组是一个缓慢的操作,因为必须分配新内存并且必须复制整个数组。对B的每一行执行此操作效率不高。如果可以,请避免这种情况。

如果事先知道Aminors(B)(见下文)的形状,最好制作一个足够大的数组,以便从一开始就适应它们。

有许多人要做你要求的事情。只要np.lib.recfunctions.stack_arraysA的dtypes相同,@ seberg的B想法就会成为可行的解决方案。

这是另一种可能性,即使B具有不同的dtype,或者只是一个ndarray或列表列表,它也会起作用。

import itertools
import numpy as np

def minors(arr):
    for row in arr:
        row = list(row)
        for i, elt in enumerate(row):
            if elt != 0:
                for val in row[:i]+[0]+row[i+1:]:
                    yield val

A = np.recarray((3,),dtype=[('x',float), ('y', float), ('z',float)])
B = [(7.0, 0.0, 7.0), (16.0, 0.0, 1.0)]

C = np.fromiter(itertools.chain(A.view(float), minors(B)), dtype = float)
C = C.view(A.dtype)