如何在 Python 中部分读取文本文件并连接各个部分以有效地分析和绘制直方图?

How to read a text file partially in Python and join the parts to analyze and plot a histogram efficiently?

提问人:Kia 提问时间:5/25/2023 最后编辑:mkrieger1Kia 更新时间:6/21/2023 访问量:42

问:

我遇到读取txt格式文件的问题。该文件包含大量数据(88604154行,2695.7893953323364 MB),我必须分析数据,然后绘制它们的直方图。

问题是计算机需要很长时间才能读取这么多数据,所以我认为我可以读取部分数据并将部分数据加在一起。我做了一些搜索,想出了这个代码:

import resource

file_name = '/home/lam/Downloads/C3--Trace--00001.txt'

lines_num = []
for i in range(1,50001):
    lines_num.append(i)

with open (r"/home/lam/Downloads/C3--Trace--00001.txt", 'r') as fp:
    lines = []
    for i, line in enumerate(fp):
        if i in lines_num:
            lines.append(line.strip())
        elif i > 50001:
            break
txt_file.close()        

有了这个,我可以拥有一定数量的行(例如,从第一行到 50000),但我想重复代码 1775 次,以便读取所有数据,然后将它们全部附加到一个列表中。如何为此编写函数?

Python 文本 读取行

评论


答:

0赞 Kushim 5/25/2023 #1

您需要分块读取,直到没有更多可用的分块:

with open(r"/home/lam/Downloads/C3--Trace--00001.txt", 'r') as src, open("sink.txt", 'w') as sink:
  chunk_size = 1024 * 1024 # 1024 * 1024 byte = 1 mb
  while True:
    chunk = src.read(chunk_size)
    if not chunk:
      break
    sink.write(chunk)

在这里,我读取块大小,然后将该数据写入另一个文件。

read 函数会自动移动指针,因此无需提供索引。

您也可以使用您共享的代码,但删除中断异常:

file_name = f"/home/lam/Downloads/C3--Trace--00001.txt"

with open (file_name, 'r') as fp:
    lines = []
    for i, line in enumerate(fp):
        lines.append(line.strip())

如何计算平均值的示例:

import statistics

means = []
total_nums = 0

with open(r"./info.txt", 'r', newline="\n") as src:
  for line in src:
    line = [int(num) for num in line.split(",")]
    mean = statistics.mean(line)
    num = len(line)
    means.append({"num": num, "mean": mean})
    total_nums += num

total_mean = 0
for mean in means:
    total_mean += mean["mean"] * (mean["num"] / total_nums)

评论

0赞 Kushim 6/13/2023
@Kia如果它崩溃是因为您可能内存不足,通过读取块,您可以进行某种过滤或聚合,以减少您拥有的行数或数据点数,然后绘制新的过滤列表。我写了另一个文件作为例子,你基本上可以用这些信息做任何你想做的事。在处理使计算机崩溃的 dat 时,您可能要研究的另一件事是 pyspark。该库允许您创建一个惰性 DataFrame,然后您可以使用它的内置方法进行绘图。请提供您的数据示例行
0赞 Kia 6/14/2023
是的,有问题并解决了
0赞 Kia 6/14/2023
但是当我想计算数据的平均值时,我遇到了这个错误:MemoryError:无法为形状为 (2613) 且数据类型为 <U1048576 的数组分配 10.2 GiB,这意味着我有太多的数据。我可以只对一大块数据(最中间的数据)使用平均值并将其用于整个数据吗?
0赞 Kushim 6/21/2023
从数学上讲,您可以计算每个块的平均值并将此平均值存储在数组中,然后通过执行平均值来计算整个数据集的平均值。在您的情况下,块应该具有相同的长度,但为了确保您可以存储用于计算平均值和 acualt 平均值的数字数量,并保留一个变量来求和数字数量,最后您可以通过将用于每个平均值的数字除以数字总数来计算权重。我将用一个例子来更新我的答案