我正在尝试找出将大熊猫DataFrame写入S3文件系统的最快方法。我目前正在尝试两种方法:
1)通过gzip压缩(BytesIO)和boto3
gz_buffer = BytesIO()
with gzip.GzipFile(mode='w', fileobj=gz_buffer) as gz_file:
df.to_csv(TextIOWrapper(gz_file, 'utf8'), index=False)
s3_resource = boto3.resource('s3')
s3_object = s3_resource.Object(bucket, s3_path + name_zip)
s3_object.put(Body=gz_buffer.getvalue())
对于700万行的数据帧,大约需要420秒才能写入S3。
2)通过不压缩即可写入csv文件(StringIO缓冲区)
csv_buffer = StringIO()
data.to_csv(csv_buffer)
s3_resource = boto3.resource('s3')
s3_resource.Object(bucket, s3_path + name_csv).put(Body=csv_buffer.getvalue())
这大约需要371秒...
问题是: 还有其他更快的方法可以将熊猫数据帧写入S3吗?
答案 0 :(得分:3)
使用分段上传可以更快地传输到S3。压缩使文件更小,因此也有帮助。
import boto3
s3 = boto3.client('s3')
csv_buffer = BytesIO()
df.to_csv(csv_buffer, compression='gzip')
# multipart upload
# use boto3.s3.transfer.TransferConfig if you need to tune part size or other settings
s3.upload_fileobj(csv_buffer, bucket, key)
s3.upload_fileobj
的文档在这里:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.upload_fileobj
答案 1 :(得分:0)
您可以尝试将if (value) {
snapshot.forEach(function (childSnapshot) {
var myDate = childSnapshot.val();
days.push(new Date(myDate.date)); //ARRAY DOES NOT SORT, yet...
});
days.sort(date_sort_asc); // <-- Do it here
}
和s3fs
压缩一起使用,以上传到S3。 pandas
或StringIO
占用内存。
BytesIO
答案 2 :(得分:0)
首先,检查您是否正在写与笔记本位于相同区域的存储桶。
第二,您可以尝试使用 multi-part 进行上传的选项,该方法可以接收大于几GB的文件并并行上传:
from boto3.s3.transfer import TransferConfig
def s3_upload_file(args):
s3 = boto3.resource('s3')
GB = 1024 ** 3
config = TransferConfig(multipart_threshold=5 * GB)
s3.meta.client.upload_file(args.path, args.bucket, os.path.basename(args.path),Config=config)
答案 3 :(得分:0)
这确实取决于内容,但这与boto3
无关。首先尝试将DataFrame
本地转储,看看最快的速度和您得到的大小。
以下是一些我们发现很快的建议,对于几MB到超过2GB的情况(尽管对于超过2GB的情况,您确实需要镶木地板并将其拆分为镶木地板数据集):
很多混合的文本/数字数据(面向SQL的内容):使用df.to_parquet(file)
。
大多数数值数据(例如,如果您的列df.dtypes
表示一个快乐的numpy
单一类型的数组,而不是Object
):则可以尝试df_to_hdf(file, 'key')
。
一点建议:尝试将df
分成一些对您有意义的碎片(例如,按时间序列划分时间)。尤其是如果您对单个分片(例如,时间序列中的最后一个分片)进行了大量更新,那么下载/上传的速度将大大提高。
我们发现,HDF5体积更大(未压缩),但是它们从内存中快速地保存/加载到内存中。实木复合地板默认情况下是经过快速压缩的,因此它们通常会较小(当然,这取决于数据的熵;如果保存完全随机数,则会对您造成不利影响)。
对于boto3
客户端,默认情况下multipart_chunksize
和multipart_threshold
均为8MB,这通常是个不错的选择。您可以通过以下方式进行检查:
tc = boto3.s3.transfer.TransferConfig()
print(f'chunksize: {tc.multipart_chunksize}, threshold: {tc.multipart_threshold}')
此外,默认值是每次上传使用10个线程(除非对象的大小大于上述阈值,否则不会执行任何操作)。
另一个问题是如何有效地上传许多文件。 {strong> 不能通过TransferConfig
中的任何定义来处理。但是我离题了,最初的问题是关于单个对象的。