我想创建一个包含三列的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
。
我是否正在解决这个问题,或者我应该尝试完全不同的方式?
答案 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')