将多个不同dtype的Numpy数组写为CSV文件的列

时间:2016-08-27 16:44:30

标签: python csv numpy

将不同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,但如果数组的类型不同,我不清楚如何使用它。

2 个答案:

答案 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

因此,只要您处理数值,简单连接就像更复杂的结构化方法一样好。

============