将不同dtype的多个numpy数组编写为单个CSV文件的不同列的最佳方法是什么?
例如,给定以下数组:
array([[1, 2],
[3, 4],
[5, 6]])
array([[ 10., 20.],
[ 30., 40.],
[ 50., 60.]])
我想获取一个文件(分隔符不相关):
1 2 10.0 20.0
3 4 30.0 40.0
5 6 50.0 60.0
最理想的是,我希望能够以这种方式编写数组列表,其中每个数组的格式/ dtype可以不同。
我尝试查看savetxt
,但如果数组的类型不同,我不清楚如何使用它。
答案 0 :(得分:1)
使用<input type="text" id="your-id" value="dd/mm/yy">
以沿第二轴连接数组,然后使用np.savetxt
以便以文本格式保存数组。
np.concatenate
请注意,np.savetxt
也接受其他参数,例如import numpy as np
a = np.array([[1, 2],
[3, 4],
[5, 6]])
b = np. array([[10., 20.],
[30., 40.],
[50., 60.]])
np.savetxt('filename.csv', np.concatenate((a,b), axis=1))
。
delimiter
答案 1 :(得分:1)
In [38]: a=np.arange(1,7).reshape(3,2)
In [39]: b=np.arange(10,70.,10).reshape(3,2)
In [40]: c=np.concatenate((a,b),axis=1)
In [41]: c
Out[41]:
array([[ 1., 2., 10., 20.],
[ 3., 4., 30., 40.],
[ 5., 6., 50., 60.]])
所有值都是浮点数;默认savetxt
是一般浮动:
In [43]: np.savetxt('test.csv',c)
In [44]: cat test.csv
1.000000000000000000e+00 2.000000000000000000e+00 1.000000000000000000e+01 2.000000000000000000e+01
3.000000000000000000e+00 4.000000000000000000e+00 3.000000000000000000e+01 4.000000000000000000e+01
5.000000000000000000e+00 6.000000000000000000e+00 5.000000000000000000e+01 6.000000000000000000e+01
使用自定义fmt
我可以获得:
In [46]: np.savetxt('test.csv',c,fmt='%2d %2d %5.1f %5.1f')
In [47]: cat test.csv
1 2 10.0 20.0
3 4 30.0 40.0
5 6 50.0 60.0
更一般地说,我们可以使用复合dtype制作c
。这里不需要浮动和整数,但是使用字符串它会很重要。但是我们仍然需要一个很长的fmt
才能正确显示列。
np.rec.fromarrays
是一种生成结构化数组的简便方法。不幸的是,它只适用于扁平化阵列。所以对于你的(3,2)数组,我需要单独列出列。
In [52]: c = np.rec.fromarrays((a[:,0],a[:,1],b[:,0],b[:,1]))
In [53]: c
Out[53]:
rec.array([(1, 2, 10.0, 20.0), (3, 4, 30.0, 40.0), (5, 6, 50.0, 60.0)],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<f8'), ('f3', '<f8')])
In [54]: np.savetxt('test.csv',c,fmt='%2d %2d %5.1f %5.1f')
In [55]: cat test.csv
1 2 10.0 20.0
3 4 30.0 40.0
5 6 50.0 60.0
我使用相同的savetxt
。
我还可以创建一个包含2个字段的结构化数组,每个字段为2列。我不确定savetxt
是否适用。
savetxt
基本上遍历数组的第一维,并对每一行进行格式化写入,粗略地说:
for row in arr:
f.write(fmt%tuple(row))
其中fmt
来自您的参数。
编写自己的迭代2个数组的版本并不难,并为每对行执行单独的格式化写入。
for r1,r2 in zip(a,b):
print('%2d %2d'%tuple(r1), '%5.1f %5.1f'%tuple(r2))
===================
尝试复合dtype
In [60]: np.dtype('2i,2f')
Out[60]: dtype([('f0', '<i4', (2,)), ('f1', '<f4', (2,))])
In [61]: c=np.zeros(a.shape[0], np.dtype('2i,2f'))
In [62]: c['f0']=a
In [63]: c['f1']=b
In [64]: c
Out[64]:
array([([1, 2], [10.0, 20.0]), ([3, 4], [30.0, 40.0]),
([5, 6], [50.0, 60.0])],
dtype=[('f0', '<i4', (2,)), ('f1', '<f4', (2,))])
In [65]: np.savetxt('test.csv',c,fmt='%2d %2d %5.1f %5.1f')
---
ValueError: fmt has wrong number of % formats: %2d %2d %5.1f %5.1f
所以编写像这样的复合dtype不起作用。考虑到一行c
看起来像:
In [69]: tuple(c[0])
Out[69]: (array([1, 2], dtype=int32), array([ 10., 20.], dtype=float32))
我不应该感到惊讶。
我可以使用%s
格式保存这两个块,但这会留下括号。
In [66]: np.savetxt('test.csv',c,fmt='%s %s')
In [67]: cat test.csv
[1 2] [ 10. 20.]
[3 4] [ 30. 40.]
[5 6] [ 50. 60.]
我认为有np.rec
函数可以使dtype变平。但我也可以用view
:
In [72]: np.savetxt('test.csv',c.view('i,i,f,f'),fmt='%2d %2d %5.1f %5.1f')
In [73]: cat test.csv
1 2 10.0 20.0
3 4 30.0 40.0
5 6 50.0 60.0
因此,只要您处理数值,简单连接就像更复杂的结构化方法一样好。
============