如何使用Python从文件中的特定位置读取到特定位置?

时间:2019-12-22 14:52:13

标签: python numpy file

当前,我正在做:

    source_noise = np.fromfile('data/noise/' + source + '_16k.dat', sep='\n')
    source_noise_start = np.random.randint(
        0, len(source_noise) - len(audio_array))
    source_noise = source_noise[source_noise_start:
                                source_noise_start + len(audio_array)]

我的文件如下:

  -5.3302745e+02
  -5.3985005e+02
  -5.8963920e+02
  -6.5875741e+02
  -5.7371864e+02
  -2.0796765e+02
   2.8152341e+02
   6.5398089e+02
   8.6053581e+02

..等等。

这需要我读取整个文件,而我要做的只是读取文件的一部分。我有什么办法可以比现在做的更快的使用Python?

2 个答案:

答案 0 :(得分:1)

您可以使用seek方法在文件内移动并读取特定位置。

文件数据->“ hello world”

's3://sagemaker-eu-central-1-123456789/test/sagemaker/sklearncontainer/test'

答案 1 :(得分:1)

您的文件包含行,因此seek()本身几乎没有用,因为它会将文件偏移 bytes 。这意味着如果需要正确的结果,则需要非常仔细地阅读文件,否则最终将没有-符号或缺少十进制数字,否则文本将在数字中间被切掉。 / p>

更不用说一些怪癖,例如在科学记号eN与纯浮点数之间进行切换,如果您也转储以提交错误的内容也可能会发生这种情况。

现在开始阅读,Python允许您使用readlines(hint=-1)

  

可以指定提示来控制读取的行数:如果到目前为止所有行的总大小(以字节/字符为单位)超过提示,将不再读取更多行。

因此:

  

test.txt

123
456
789
012
345
678
  

控制台

>>> with open("test.txt") as f:
...     print(f.readlines(5))
...     print(f.readlines(9))
... 
['123\n', '456\n']
['789\n', '012\n', '345\n']

我还没有测量它,但是如果您不想处理线条/不想使用seek()可能会成为Python中最快的方法,那可能是最终,由于您解析的解决方案不够理想,速度甚至会变慢。

我对“ ...从特定位置到特定位置?”感到困惑。如果不打算进行解析,那么解决方案也可能只是一些bash脚本或类似的东西,但您必须知道文件中的行数(readlines(hint=-1)函数的替代方法):

with open(file) as inp:
    with open(file2) as out:
        for idx in range(num_of_lines - 1):
            line = inp.readline(idx)
            if not some_logic(line):
                continue
            out.write(line)

注意:with的嵌套仅是由于跳过了先读取整个文件然后再检查+在其他位置写入的开销。

尽管如此,您仍然使用numpy,这只是Cython或C / C ++库的一小步。这意味着,您可以跳过Python的开销,而直接使用Cython或C读取文件。

mmapmmap vs ifstream vs fread

Here is an article实际上是在测量:

  • Python代码(readline()
  • Cython(只是虚拟编译),
  • C(cimport中的{stdio.h使用getline()(找不到C引用:/))
  • C ++(似乎在图中被错误地标记为C

这似乎是最有效的代码,它需要进行一些清理和精简一些行,如果您想尝试mmap或其他有趣的阅读方法,它应该可以给您一个思路。我对此没有测量值:

  

依赖项

apt install build-essential  # gcc, etc
pip install cython
  

setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(
    name="test",
    ext_modules = cythonize("test.pyx")
)
  

test.pyx

from libc.stdio cimport *

cdef extern from "stdio.h":
    FILE *fopen(const char *, const char *)
    int fclose(FILE *)
    ssize_t getline(char **, size_t *, FILE *)

def read_file(filename):
    filename_byte_string = filename.encode("UTF-8")
    cdef char* fname = filename_byte_string

    cdef FILE* cfile
    cfile = fopen(fname, "rb")
    if cfile == NULL:
        raise FileNotFoundError(2, "No such file or directory: '%s'" % filename)

    cdef char * line = NULL
    cdef size_t l = 0
    cdef ssize_t read
    cdef list result = []

    while True:
        read = getline(&line, &l, cfile)
        if read == -1:
            break
        result.append(line)

    fclose(cfile)
    return result
  

外壳

pip install --editable .
  

控制台

from test import read_file
lines = read_file(file)