我使用熊猫和python从数据库中的表中提取数据,并将其写入windows文件目录中的CSV文件。
如果文件大小超过一定数量的内存,我想将数据分割成多个文件。
例如,阈值为32 MB,如果我的CSV数据文件小于32 MB,我将把数据写入一个CSV文件中。但是,如果文件大小可能超过32 MB,例如50 MB,我将将数据拆分并写入两个文件,一个为32 MB,另一个为(50-32)=18 MB。
我发现的唯一一件事是如何使用memory_usage方法或python的getsizeof函数来找到数据only所容纳的内存。但我无法将该内存与数据文件的实际大小联系起来。进程内内存通常比文件大小大5-10倍.
谢谢你的建议。
发布于 2022-06-13 17:33:05
在你的代码中做一些检查。将DataFrame的一部分作为csv写入io.StringIO()对象,并检查该对象的长度;使用该对象超过或低于目标的百分比来重新定义DataFrame切片;重复;当sat写入磁盘时,使用该切片大小写入其余部分。
就像..。
import StringIO from io
g = StringIO()
n = 100
limit = 3000
tolerance = .90
while True:
data[:n].to_csv(g)
p = g.tell()/limit
print(n,g.tell(),p)
if tolerance < p <= 1:
break
else:
n = int(n/p)
g = StringIO()
if n >= nrows: break
_ = input('?')
# with open(somefilename, 'w') as f:
# g.seek(0)
# f.write(g.read())
# some type of loop where succesive slices of size n are written to a new file.
# [0n:1n], [1n:2n], [2n:3n] ...请注意,.tell()的文档说:
将当前流位置作为不透明数字返回。该数字通常不表示基础二进制存储中的字节数。
我的经验是,流末尾的.tell()是io.StringIO对象的字节数--我一定遗漏了什么。也许,如果包含多字节unicode内容,情况就不同了。
也许使用csv字符串的长度进行测试更安全,在这种情况下,不需要io.StringIO对象。这可能更好/更简单。如果我能够首先阅读docs first,我就不会提出io.StringIO版本- #@$%#@。
n = 100
limit = 3000
tolerance = .90
while True:
q = data[:n].to_csv()
p = len(q)/limit
print(f'n:{n}, len(q):{len(q)}, p:{p}')
if tolerance < p <= 1:
break
else:
n = int(n/p)
if n >= nrows: break
_ = input('?') 另一个警告:如果第一个n行的每行字符数与其他n个大小的切片有很大差异,如果在编写前不测试和调整每个切片,则有可能超调或低于限制。
例如,设置:
import numpy as np
import pandas as pd
nrows = 1000
data = pd.DataFrame(np.random.randint(0,100,size=(nrows, 4)), columns=list('ABCD'))https://stackoverflow.com/questions/72606258
复制相似问题