我是Python新手,我正在尝试转换2d numpy数组,例如:
b='191.250\t0.00\t0\t1\n191.251\t0.00\t0\t1\n191.252\t0.00\t0\t1\n'
到一个字符串,其中列条目由一个分隔符分隔' \ t'并且这些行由另一个分隔符分隔' \ 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))
首先,我通过以下方式创建数组:
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:
方法1:
b=''
for i in range(0,a.shape[0]):
b+='\t'.join(['%0.3f' %x for x in a[i,:]])+'\n'
b
方法2:
b = '\n'.join('\t'.join('%0.3f' %x for x in y) for y in a)+'\n'
但是,我猜测有更好的方法可以产生a和b。我正在寻找最有效的方法(即内存,时间,代码紧凑性)来创建a和b。
跟进问题
谢谢Mike,
y=b.split('\n')[:-1]
z=[y[i].split('\t') for i in range(0,len(y))]
a=numpy.array(z,dtype=float)
为我工作,但我有一些跟进问题(这不适合评论部分):
方法1
import re
a=numpy.array(filter(None,re.split('[\n\t]+',b)),dtype=float).reshape(-1,4)
方法2
<html>
<head>
<body>
<div class="display_wait_overlay">
<div class="section wrapper">
<div id="test-not" class="fade modal text-left">
<div id="monthlyinvoiceremainder" class="fade modal text-left">
<div id="monthlyinvoiceremainderBox" class="btm_bx">
<div id="depositDetailsResponse" class="fade modal text-left">
<div id="depositDetails" class="fade modal text-left">
<footer class="footer navbar_custom" style="">
<div class="datepicker datepicker-dropdown dropdown-menu datepicker-orient-left datepicker-orient-bottom" style="display: block; top: 155.933px; left: 758.133px;">
<div class="datepicker-days" style="display: none;">
<div class="datepicker-months" style="display: none;">
<div class="datepicker-years" style="display: block;">
<table class="table-condensed">
<thead>
<tr>
<th class="prev" style="visibility: visible;">«</th>
<th class="datepicker-switch" colspan="5">2010-2019</th>
<th class="next" style="visibility: hidden;">»</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="7">
<span class="year old">2009</span>
<span class="year">2010</span>
<span class="year">2011</span>
<span class="year">2012</span>
<span class="year">2013</span>
<span class="year">2014</span>
<span class="year">2015</span>
<span class="year disabled">2016</span>
<span class="year disabled">2017</span>
<span class="year disabled">2018</span>
<span class="year disabled">2019</span>
<span class="year new disabled">2020</span>
</td>
</tr>
</tbody>
<tfoot>
</table>
</div>
</div>
</body>
</html>
有更好的方法吗?
答案 0 :(得分: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()
相比可以使+=
更快。
答案 1 :(得分:0)
使用Python3,我只用了一行:
str(a).replace('[','').replace(']','').replace('\n',' ')+' '
输出(固定宽度):
'191.25 0. 0. 1. 191.251 0. 0. 1. 191.252 0. 0. 1. '