2015-08-15 104 views
4

我试图处理存储在一个文本文件,它看起来像这样test.dat数据:但是如何只读取文本文件中的特定行?

-1411.85 2.6888 -2.09945 -0.495947 0.835799 0.215353 0.695579 
-1411.72 2.82683 -0.135555 0.928033 -0.196493 -0.183131 -0.865999 
-1412.53 0.379297 -1.00048 -0.654541 -0.0906588 0.401206 0.44239 
-1409.59 -0.0794765 -2.68794 -0.84847 0.931357 -0.31156 0.552622 
-1401.63 -0.0235102 -1.05206 0.065747 -0.106863 -0.177157 -0.549252 
.... 
.... 

该文件是几个GB,我就非常喜欢读它,行的小块。我想使用numpy'sloadtxt函数,因为这会将所有内容快速转换为numpy array。然而,我至今还没有能够管理的功能似乎只提供了这样的列选择:

data = np.loadtxt("test.dat", delimiter=' ', skiprows=1, usecols=range(1,7)) 

任何想法如何实现这一目标?如果loadtxt不可用Python中提供的其他选项?

+0

loadtxt的fname参数可以是一个生成器,所以要读取小块的行使用文件读取生成器,如http://stackoverflow.com/questions/519633/lazy-method-for-reading-big中显示的文件读取生成器-python中的文件,但转换为只读取少量的行而不是字节。 – 2015-08-15 17:10:37

+1

另请参见:http://stackoverflow.com/a/27962976/901925 - “用numpy的genfromtxt读取每第n行的最快方法” – hpaulj

回答

1

hpaulj在他的评论中指出了我的正确方向。

使用下面的代码工作完美的我:

import numpy as np 
import itertools 
with open('test.dat') as f_in: 
    x = np.genfromtxt(itertools.islice(f_in, 1, 12, None), dtype=float) 
    print x[0,:] 

非常感谢!

2

如果你可以使用pandas,这会更容易些:如果你想读说每个k

In [2]: import pandas as pd 

In [3]: df = pd.read_table('test.dat', delimiter=' ', skiprows=1, usecols=range(1,7), nrows=3, header=None) 

In [4]: df.values 
Out[4]: 
array([[ 2.82683 , -0.135555 , 0.928033 , -0.196493 , -0.183131 , 
     -0.865999 ], 
     [ 0.379297 , -1.00048 , -0.654541 , -0.0906588, 0.401206 , 
     0.44239 ], 
     [-0.0794765, -2.68794 , -0.84847 , 0.931357 , -0.31156 , 
     0.552622 ]]) 

编辑

,您可以指定chunksize。例如,

reader = pd.read_table('test.dat', delimiter=' ', usecols=range(1,7), header=None, chunksize=2) 
for chunk in reader: 
    print(chunk.values) 

日期:

[[ 2.6888 -2.09945 -0.495947 0.835799 0.215353 0.695579] 
[ 2.82683 -0.135555 0.928033 -0.196493 -0.183131 -0.865999]] 
[[ 0.379297 -1.00048 -0.654541 -0.0906588 0.401206 0.44239 ] 
[-0.0794765 -2.68794 -0.84847 0.931357 -0.31156 0.552622 ]] 
[[-0.0235102 -1.05206 0.065747 -0.106863 -0.177157 -0.549252 ]] 

你必须处理如何将它们存储在for循环,如你所愿。请注意,在这种情况下,readerTextFileReader,而不是DataFrame,因此您可以懒惰地遍历它。

有关更多详细信息,请参阅this

+0

我不明白我会如何读取前三个,然后是第二个三个等等。你能解释一下吗?感谢您的努力! –

+0

你的意思是把前三部分写入ndarray,然后将下三部分写入另一个ndarray,等等? – yangjie

+0

是的,那就是我需要的! –

1

您可能想要使用itertools配方。

from itertools import izip_longest 
import numpy as np 


def grouper(n, iterable, fillvalue=None): 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 


def lazy_reader(fp, nlines, sep, skiprows, usecols): 
    with open(fp) as inp: 
     for chunk in grouper(nlines, inp, ""): 
      yield np.loadtxt(chunk, delimiter=sep, skiprows=skiprows, usecols=usecols) 

该函数返回一个数组的生成器。

lazy_data = lazy_reader(...) 
next(lazy_data) # this will give you the next chunk 
# or you can iterate 
for chunk in lazy_data: 
    ...