我想将存储在s3中的大型csv文件(〜100-500mb)加载到pandas数据帧。该代码在ec2实例内的docker容器中运行。我看到三种访问数据的方法
aws_object = boto3.resource('s3',
"useast1",
aws_access_key_id='xxxx',
aws_secret_access_key= 'xxx')
aws_object.Bucket(s3_bucket).download_file(s3_key,download_folder+os.sep+file_name)
aws_object = boto3.resource('s3',
"useast1",
aws_access_key_id='xxxx',
aws_secret_access_key='xxx')
csv_string = s3_object['Body'].read()
df_head = pd.read_csv(io.BytesIO(csv_string),
encoding="ISO-8859-1",
nrows=5,
header=None)
data = pd.read_csv('s3:/bucket....csv')
每种方法的优缺点是什么?推荐哪种方法?将文件下载到本地文件系统是否更有效率?在处理文件时,我可能需要几次将文件加载到单独的数据帧中。
答案 0 :(得分:1)
下载csv会将其复制到您的本地存储中,这样做的一个好处是,您可以根据需要对文件进行就地编辑,并且后端访问速度更快。另外,由于该副本是本地副本,因此您无需互联网连接即可播放数据。显而易见的缺点是,随着时间的流逝,您将使用大量存储空间。
流传输具有远程访问数据的明显好处,因此您不会用完自己的存储。缺点是它比访问下载的文件要慢,因为它将依赖于您的Internet速度,并且将不断使用带宽来查看文件。这只是意味着随着时间的流逝,如果您一次在多个文件上运行该程序,带宽将迅速堆积,并可能使其他一些互联网用户感到愤怒。
直接从S3路径读取文件可能是最好的选择。这会将数据作为熊猫数据帧存储在内存中,并且仅访问一次数据(以进行存储)。然后,对数据帧的所有进一步更改将应用于内存中的对象。
最佳方法将取决于您的下游应用程序。我认为下载csv文件不会是最实用的方法,因为您的代码指向s3存储桶。下载数据的唯一实际目的是在没有互联网的情况下访问数据(在这种情况下,您将下载代码外部的文件,然后从本地PC访问它)。
您的代码2和3是多余的。当您流式传输数据时,虽然还不错,但是无论如何都将其作为数据帧对象加载,这违反了将文件作为流读取的目的。数据帧中的数据量将相同,因为您最终要存储它。我认为方法3将是您最好的选择,因为它可以消除不必要的冗余。