pandas 一个Python程序,只将excel文件的某个兆字节加载到 Dataframe 中,并将其转换为字符串

r3i60tvu  于 2023-03-06  发布在  Python
关注(0)|答案(1)|浏览(95)

我对Python还是个新手,我正在学习pandas库的一些用法,但是我找不到一种方法,可以只将excel文件的一部分加载到内存中并使用它,例如,如果我将内存限制设置为1MB,程序应该能够从大于1MB的excel文件中读取前1MB。
here的回答中,我看到了一个加载特定行数的选项,但是我不知道输入文件中的行数,也不知道这段代码读取了多少字节的数据。
是否有一种方法可以迭代地加载行数,其中读取的字节数也可以在每次迭代中计算,并且可以累积求和?

0pizxfdo

0pizxfdo1#

1.)换算系数

“品尝”工作表头部附近的一些示例数据,计算每行的平均字节数,然后使用它来预测有多少行适合您的内存预算。

2.)两极

polars项目非常强调“使用更少的RAM!”和快速I/O。一个方便的.to_pandas()方法可以轻松地将polars DataFrame转换为您喜欢的格式。考虑在polars中进行过滤,然后将结果交给Pandas,并按照应用的其他部分的要求进行格式化。

3.)发电机

对于CSV,这很容易,而且绝对不会做额外的malloc。对于其他格式,我们可能会为整个工作表做分配,但这样我们绝对可以避免为不需要的行分配Pandas。
我们将使用一个dict reader,外加一个用于提前终止的发生器。

from sys import getsizeof
import openpyxl_dictreader

df = pd.DataFrame(read_initial(1_000_000, filespec, sheet))

def read_initial(budget: int, filespec: Path, sheet: str):
    size = 0
    reader = openpyxl_dictreader.DictReader(filespec, sheet)
    for row in reader:
        size += (sum(map(getsizeof, row.values()))
               + sum(map(getsizeof, row.keys())))
        if size > budget:
            break
        yield row

如果递归getsizeof的精确度不合您的口味,您可以随意使用更花哨的成本估算。
考虑在一个抛弃的python子进程中运行它,在子进程中序列化行,在父进程中反序列化行,这样任何额外的每工作表分配都将是短暂的,multiprocessing池大小为1,如果你返回一个list,它将几乎“免费”给予这样的功能。
考虑将 *.xlsx文件转换为更适合流的格式,如. csv。

相关问题