用dtypes创建一个numpy矩阵

时间:2014-08-25 13:45:01

标签: python numpy types

我想创建一个包含三列的numpy矩阵,其中前两列包含整数,第三列包含浮点数。我想从一个空矩阵开始,每次在for循环中添加一行。但是,我无法将其添加到具有特定数据类型的numpy矩阵中。这是我开始使用的代码:

import numpy as np

def grow_table():
    dat_dtype = {
        'names' : ['A', 'B', 'C'],
        'formats' : ['i', 'i', 'd']}
    S = np.zeros(0, dat_dtype) 

    X = np.array([1, 2, 3.5], dat_dtype)    
    S = np.vstack((S, X))

if __name__ == '__main__':
    grow_table()

但是,这会产生TypeError: expected a readable buffer object

然后我按如下方式更改我定义行的行:

X = np.array((1, 2, 3.5), dat_dtype)

此行已被接受。但是,现在X是一个元组。如果我尝试print X[0],我最终会得到IndexError: 0-d arrays can't be indexed。此外,我无法将X添加到S,它会给我一个ValueError: all the input array dimensions except for the concatenation axis must match exactly

接下来,我从数据类型中删除名称;在这种情况下,我最终得到ValueError: entry not a 2- or 3- tuple

我是否正在解决这个问题,或者我应该尝试完全不同的方式?

2 个答案:

答案 0 :(得分:1)

我不是混合dtypes的忠实粉丝,可以使用单独的数组,字典中的数组或pandas数据帧。无论如何,这是你如何做到的:

X = np.array([(1, 2, 3.5)], dat_dtype)
S = np.vstack((S[:,None], X, X, X))

重新打包每次迭代通常很慢,你可能最好还是制作1行数组的列表并在最后对其进行vstack,或创建具有已知大小的数组并分配给元素。

答案 1 :(得分:0)

我不是逐渐增加数组的粉丝,但这是一种方法:

import numpy as np

def grow_table():
    dt=np.dtype({'names':['A','B','C'],'formats':['i','i','d']})
    S = np.zeros(0, dtype=dt)
    for i in range(5):
        X = np.array((i, 2*i, i+.5), dtype=dt)
        S = np.hstack((S, X))
    return S

if __name__ == '__main__':
    S  = grow_table()
    print S
    print S['A']
制造

[(0, 0, 0.5) (1, 2, 1.5) (2, 4, 2.5) (3, 6, 3.5) (4, 8, 4.5)]
[0 1 2 3 4]

S以形状(0,)开头。 X的形状为();它是0d。最后S的形状为(5,)。我们必须使用hstack,因为我们正在创建一个1d数组;一系列元组。这就是你使用dtype这样的结果。此外,在为这样的数组赋值时,值必须在元组中,而不是列表。

更好的增量构建是:

def make_table(N=5):
    dt=np.dtype({'names':['A','B','C'],'formats':['i','i','d']})
    S = np.zeros(N, dtype=dt)
    for i in range(N):
        S[i] = (i, 2*i, i+.5)
    return S

甚至使用元组列表:

def better(N=5):
    dt=np.dtype({'names':['A','B','C'],'formats':['i','i','d']})
    L = [(i, 2*i, i+.5) for i in range(N)]
    return np.array(L, dtype=dt)

表示csv输出:

S = better()
np.savetxt('S.txt', S, fmt='%d, %d, %f')

产生

0, 0, 0.500000
1, 2, 1.500000
...

尝试savetxt (N,1)数组会产生一个或多个错误。

savetxt尝试撰写

 for row in S:
     write(fmt%row)

使用(N,)数组,row(0, 0, 0.5),但(N,1)[(0, 0, 0.5)]

np.savetxt('S.txt', S, fmt='%s') 

工作,制作

(0, 0, 0.5)
(1, 2, 1.5)
...

但如果您只想保存2列整数和一个浮点数,则不需要此dtype。让fmt完成所有工作:

def simple(N=5):
    return np.array([(i, 2*i, i+.5) for i in range(N)])
S = simple()
np.savetxt('S.txt',S, fmt='%d, %d, %f')