【问题标题】:Need to use seek(), tell(), next() and readline() function together需要同时使用 seek()、tell()、next() 和 readline() 函数
【发布时间】:2018-05-03 16:43:06
【问题描述】:

就我而言,我有两个 csv 文件(file1 和 file2)。

为了简化我的问题,假设我想连续读取 file1、3 x 3 和 file2 4 x 4 的元素。

file1.csv(9 行)

1,2,3
3,5,8
7,2,9
10,111,12
13,14,155
31,2,3
3,15,82
8,4,91
12,111,13

file2.csv(12 行)

55,12,17
3,6,13
72,1,91
10,0,12
1,1,73
31,2,3
3,15,61
18,6,91
13,33,13
7,1,15
9,17,42
41,8,18

在我想得到的输出中:

1,2,3 (from 1. row of file1.csv)
3,5,8 (from 2. row of file1.csv)
7,2,9 (from 3. row of file1.csv)
55,12,17  (from 1. row of file2.csv)
3,6,13  (from 2. row of file2.csv)
72,1,91  (from 3. row of file2.csv)
10,0,12  (from 4. row of file2.csv)
10,111,12  (from 4. row of file1.csv)
13,14,155  (from 5. row of file1.csv)
31,2,3  (from 6. row of file1.csv)
1,1,73  (from 5. row of file2.csv)
31,2,3  (from 6. row of file2.csv)
3,15,61  (from 7. row of file2.csv)
18,6,91  (from 8. row of file2.csv)
3,15,82  (from 7. row of file1.csv)
8,4,91  (from 8. row of file1.csv)
12,111,13  (from 9. row of file1.csv)
13,33,13  (from 9. row of file2.csv)
7,1,15  (from 10. row of file2.csv)
9,17,42  (from 11. row of file2.csv)
41,8,18  (from 12. row of file2.csv)

我的真实数据文件非常大(每个文件约 1.6 GB),我希望尽可能少地使用内存。为此,我写了一个脚本:

f1, f2, = open(pathInput1, 'r'), open(pathInput2, 'r')
position1, position2 = 0, 0

for i in range(6):
    if i%2 == 0:
        #print("file1.csv")
        sizeOfWindow = 3
        sizeOfWindowInactive = 4
        f1.seek(position1)
        data = []
        for l in range(sizeOfWindow):
            line = f1.readline()
            line = list(map(int, line[:-1].split(",")))
            data.append(line)
        data = np.array(data)
        print(data)
        [next(f2) for i in range(sizeOfWindowInactive)]
        position1 = f1.tell()
    else:
        #print("file2.csv")
        sizeOfWindow = 4
        sizeOfWindowInactive = 3
        f2.seek(position2)
        data = []
        for l in range(sizeOfWindow):
            line = f2.readline()
            line = list(map(int, line[:-1].split(",")))
            data.append(line)
        data = np.array(data)
        print(data)
        [next(f1) for i in range(sizeOfWindowInactive)]
        position2 = f2.tell()

写完这个脚本后,我注意到我不能同时使用readline()next()。现在我的问题是,如何安排我的脚本来观察相同的输出而不使用太多内存。

编辑:在我的真实案例中,我有 5 个文件,每个文件都有自己的 sizeOfWindow。根据我读取的数据,我决定使用 if 语句跳转到文件中。所以 sizeOfWindow 是根据文件固定的。我不经常阅读文件。我决定使用我读取的最后一个数据部分来跳转文件。当我读取一个文件时,我需要移动其他文件的光标而不读取它们的数据。

【问题讨论】:

  • 为了保持复杂性,您不能在非二进制文件上可靠地使用seektell(字符串解码器会妨碍您)。如果您只想交错行,则不需要这种复杂程度。
  • 我没有看到问题。每个文件描述符都有自己的“书签”。您从 file1 中读取 3 行,然后从 file2 中读取 4 行。您正在按顺序阅读每个文件:不需要seek, next,tell。重复,直到文件中的数据用完。
  • 扔掉寻找和窥视——在这里读 3 行,那里读 4 行,重复——也许事件更好(问 numpycracks)——将机器人读入不同的 narray 并在那里交错。不知道这在内存方面有多好 - 但如果您只想将它​​们打印到控制台,则不需要 80% 的代码,因为将它们打印为字符串(从文件中读取)或解析/en 都没有关系- 在打印之前列出它们...
  • @tdelaney 我从这里找到的,他们使用stackoverflow.com/questions/15594817/…
  • @Prune 不,使用 next 和 readline 是个问题。 “将 next() 方法与 readline() 等其他文件方法结合使用无法正常工作。但是,使用seek() 将文件重新定位到绝对位置将刷新预读缓冲区。” tutorialspoint.com/python/file_next.htm

标签: python readline next seek read-data


【解决方案1】:

由于您只需要顺序读取文件,因此您可以根据需要使用next(f1)next(f2)来获取您想要的行。 itertools 模块包含使这更容易的助手。 itertools.islice 将获取几行代码,因此您不需要为 next 创建自己的循环。 itertools.cycle 将在列表中交替显示项目,因此您无需跟踪下一个文件。放在一起:

import itertools
import numpy as np

with open(pathInput1) as f1, open(pathInput2) as f2:
    grab_this = ((3, f1), (4, f2))
    for num, fp in itertools.cycle(grab_this):
        data = np.array(itertools.islice(fp, num))
        if not data:
            break
        print(data)

【讨论】:

  • 能否请您阅读我在顶部的编辑。谢谢,但我已经尝试过islice(),它为我花费了很多内存。你还有别的提议吗?
  • 当我尝试你的代码时,它给了我一个错误: data = np.array(itertools.islice(fp, num)) ValueError: Stop argument for islice() must be None or an integer: 0 islice() 像这样:for line in islice(f1, sizeOfWindowInactive, None): pass 跳过不必要的行。正如我所说,我占用了更多内存,我不知道为什么
  • 我的错误。那应该是itertools.cycle。代码相当于islice((4, f2), (3, f1)),第二个参数肯定不是整数! islice(f1, sizeOfWindowInactive, None) 也不是你想要的——它消耗了整个迭代器。我更改了代码,它应该工作得更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多