使用numpy.genfromtxt限制读取的数据量,以便在matplotlib中使用。

12

我正在使用一个文本文件作为源数据并使用matplotlib绘制图形来创建Python中的图形。下面的简单逻辑效果很好。

但是,有没有一种方法可以让numpy.gentfromtxt仅从文件“temperature_logging”中读取前50行?目前它会读取整个文件。

temp = numpy.genfromtxt('temperature_logging',dtype=None,usecols=(0))
time = numpy.genfromtxt('temperature_logging',dtype=None,usecols=(1))

dates = matplotlib.dates.datestr2num(time)

pylab.plot_date(dates,temp,xdate=True,fmt='b-')

pylab.savefig('gp.png')

温度记录中的内容;

21.75 12-01-2012-15:53:35    
21.75 12-01-2012-15:54:35    
21.75 12-01-2012-15:55:35    
.
.
.
2个回答

12

numpy.genfromtxt 函数接受迭代器和文件作为输入。这意味着它可以接受 itertools.islice 函数的输出。这里,test.txt 是一个五行的文件:

>>> import itertools, numpy
>>> with open('test.txt') as t_in:
...     numpy.genfromtxt(itertools.islice(t_in, 3))
... 
array([[  1.,   2.,   3.,   4.,   5.],
       [  6.,   7.,   8.,   9.,  10.],
       [ 11.,  12.,  13.,  14.,  15.]])

有人可能认为自己处理文件IO比让numpy处理更慢,但是快速测试表明情况并非如此。genfromtxt提供了一个skip_footer关键字参数,如果您知道文件的长度,可以使用它...

>>> numpy.genfromtxt('test.txt', skip_footer=2)
array([[  1.,   2.,   3.,   4.,   5.],
       [  6.,   7.,   8.,   9.,  10.],
       [ 11.,  12.,  13.,  14.,  15.]])

…但是对一个1000行的文件进行了几次非正式测试表明,即使你只跳过了几行,使用islice仍然更快:

>>> def get(nlines, islice=itertools.islice):
...     with open('test.txt') as t_in:
...         numpy.genfromtxt(islice(t_in, nlines))
...         
>>> %timeit get(3)
1000 loops, best of 3: 338 us per loop
>>> %timeit numpy.genfromtxt('test.txt', skip_footer=997)
100 loops, best of 3: 4.92 ms per loop
>>> %timeit get(300)
100 loops, best of 3: 5.04 ms per loop
>>> %timeit numpy.genfromtxt('test.txt', skip_footer=700)
100 loops, best of 3: 8.48 ms per loop
>>> %timeit get(999)
100 loops, best of 3: 16.2 ms per loop
>>> %timeit numpy.genfromtxt('test.txt', skip_footer=1)
100 loops, best of 3: 16.7 ms per loop

非常反直觉!有人知道这是为什么吗? - fakedrake

0

虽然我对numpy不是很了解,但可能的一个解决方案是使用stringio类。

这允许您使用普通文件IO(也有字节版本)将实际需要的数据加载到字符串中,从字符串创建类似文件的对象,并将其传递给numpy。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接