我是Python的新手,正在尝试转换2d numpy数组,例如:
a=numpy.array([[191.25,0,0,1],[191.251,0,0,1],[191.252,0,0,1]])
到一个字符串,其中列条目由一个定界符'\ t'分隔,行由另一个定界符'\ n'分隔,并控制每一列的精度,以得到:
b='191.250\t0.00\t0\t1\n191.251\t0.00\t0\t1\n191.252\t0.00\t0\t1\n'
首先,我通过以下方式创建数组:
import numpy as np
col1=np.arange(191.25,196.275,.001)[:, np.newaxis]
nrows=col1.shape[0]
col2=np.zeros((nrows,1),dtype=np.int)
col3=np.zeros((nrows,1),dtype=np.int)
col4=np.ones((nrows,1),dtype=np.int)
a=np.hstack((col1,col2,col3,col4))
然后我通过2种方法之一产生b:
方法1:
b=''
for i in range(0,a.shape[0]):
for j in range(0,a.shape[1]-1):
b+=str(a[i,j])+'\t'
b+=str(a[i,-1])+'\n'
b
方法2:
b=''
for i in range(0,a.shape[0]):
b+='\t'.join(['%0.3f' %x for x in a[i,:]])+'\n'
b
但是,我猜想有更好的方法来产生a和b。我正在寻找创建a和b的最有效方法(即内存,时间,代码紧凑性)。
跟进问题
谢谢麦克,
b = '\n'.join('\t'.join('%0.3f' %x for x in y) for y in a)+'\n'
为我工作,但我有一些后续问题(在评论部分不适合):
方法1
y=b.split('\n')[:-1]
z=[y[i].split('\t') for i in range(0,len(y))]
a=numpy.array(z,dtype=float)
方法2
import re
a=numpy.array(filter(None,re.split('[\n\t]+',b)),dtype=float).reshape(-1,4)
还有更好的方法吗?
单线将做:
b = '\n'.join('\t'.join('%0.3f' %x for x in y) for y in a)
使用简单的示例:
>>> a = np.arange(25, dtype=float).reshape(5, 5)
>>> a
array([[ 0., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 9.],
[ 10., 11., 12., 13., 14.],
[ 15., 16., 17., 18., 19.],
[ 20., 21., 22., 23., 24.]])
此:
b = '\n'.join('\t'.join('%0.3f' %x for x in y) for y in a)
print(b)
打印此:
0.000 1.000 2.000 3.000 4.000
5.000 6.000 7.000 8.000 9.000
10.000 11.000 12.000 13.000 14.000
15.000 16.000 17.000 18.000 19.000
20.000 21.000 22.000 23.000 24.000
您已经在第二种方法中使用了列表理解。在这里,我们有一个生成器表达式,它看起来完全像一个列表理解。唯一的语法差异是[]
被()
代替。 generator expression不会建立列表,而是将所谓的生成器交给join
。最后,它具有相同的效果,但是跳过了构建此中间列表的步骤。
这样的表达式中可以有多个for
,这使其嵌套了。这个:
b = '\n'.join('\t'.join('%0.3f' %x for x in y) for y in a)
等效于:
res = []
for y in a:
res.append('\t'.join('%0.3f' %x for x in y))
b = '\n'.join(res)
我在IPython Notebook中使用%%timeit
:
%%timeit
b = '\n'.join('\t'.join('%0.3f' %x for x in y) for y in a)
10 loops, best of 3: 42.4 ms per loop
%%timeit
b=''
for i in range(0,a.shape[0]):
for j in range(0,a.shape[1]-1):
b+=str(a[i,j])+'\t'
b+=str(a[i,-1])+'\n'
10 loops, best of 3: 50.2 ms per loop
%%timeit
b=''
for i in range(0,a.shape[0]):
b+='\t'.join(['%0.3f' %x for x in a[i,:]])+'\n'
10 loops, best of 3: 43.8 ms per loop
看起来它们的速度差不多。实际上,+=
是在CPython中优化的。否则,它将比join()
方法慢得多。其他Python实现(例如Jython或PyPy)可能会显示出更大的时差,并使join()
的速度比+=
快得多。
使用Python3,我只用了一行:
str(a).replace('[','').replace(']','').replace('\n',' ')+' '
输出(固定宽度):
'191.25 0. 0. 1. 191.251 0. 0. 1. 191.252 0. 0. 1. '