Tengo un DataFrame de pandas que quiero cargar en un nuevo archivo CSV. El problema es que no quiero guardar el archivo localmente antes de transferirlo a s3. ¿Existe algún método como to_csv para escribir el marco de datos en s3 directamente? Estoy usando boto3.
Esto es lo que tengo hasta ahora:
import boto3
s3 = boto3.client('s3', aws_access_key_id='key', aws_secret_access_key='secret_key')
read_file = s3.get_object(Bucket, Key)
df = pd.read_csv(read_file['Body'])
# Make alterations to DataFrame
# Then export DataFrame to CSV through direct transfer to s3
df.to_csv('s3://mybucket/dfs/somedf.csv')
. stackoverflow.com/a/56275519/908886 para obtener más información.Respuestas:
Puedes usar:
fuente
TypeError: unicode argument expected, got 'str'
error al usarStringIO
. Lo uséBytesIO
y funcionó perfectamente bien. Nota: esto fue en Python 2.7bucket
objeto? ¿cómo creaste eso?bucket
es donde almacena objetos en S3. El código asume que ya ha creado el destino (piense: directorio) donde almacenar esto. Ver documentos de S3Puede utilizar directamente la ruta S3. Estoy usando Pandas 0.24.1
Nota de lanzamiento:
fuente
NoCredentialsError: Unable to locate credentials
. ¿Alguna sugerencia?NotImplementedError: Text mode not supported, use mode='wb' and manage bytes
. ¿alguna sugerencia?Me gusta s3fs que te permite usar s3 (casi) como un sistema de archivos local.
Puedes hacerlo:
s3fs
solo admiterb
ywb
modos de abrir el archivo, es por eso que hice estobytes_to_write
.fuente
s3fs
no parece admitir el modo de adición .Esta es una respuesta más actualizada:
El problema con StringIO es que devorará su memoria. Con este método, está transmitiendo el archivo a s3, en lugar de convertirlo en una cadena y luego escribirlo en s3. Mantener el marco de datos de pandas y su copia de cadena en la memoria parece muy ineficiente.
Si está trabajando en un instante ec2, puede asignarle un rol de IAM para habilitar la escritura en s3, por lo que no necesita pasar las credenciales directamente. Sin embargo, también puede conectarse a un depósito pasando credenciales a la
S3FileSystem()
función. Ver documentación: https://s3fs.readthedocs.io/en/latest/fuente
to_csv()
. parece una implementación más limpia.botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
... Incluso hice que el bucket sea PUBLIC READ y agregué las siguientes Acciones, en mi cuenta específica de usuario de IAM, en la Política del Bucket:"Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:DeleteObject" ]
def send_to_bucket(df, fn_out, bucketname): csv_buffer = StringIO(); df.to_csv(csv_buffer); s3_resource = boto3.resource('s3'); s3_resource.Object(bucketname, fn_out).put(Body=csv_buffer.getvalue());
Si pasa
None
como primer argumento,to_csv()
los datos se devolverán como una cadena. A partir de ahí, es un paso fácil cargarlo en S3 de una vez.También debería ser posible pasar un
StringIO
objetoto_csv()
, pero usar una cadena será más fácil.fuente
None
ato_csv()
y el uso de la cadena devuelta de lo que es para crear unStringIO
objeto y luego vuelve a leer los datos.También puede utilizar AWS Data Wrangler :
Tenga en cuenta que se dividirá en varias partes, ya que lo carga en paralelo.
fuente
Descubrí que esto se puede hacer usando
client
también y no soloresource
.fuente
ya que está usando
boto3.client()
, intente:fuente
Encontré una solución muy simple que parece estar funcionando:
Espero que ayude !
fuente
Leí un csv con dos columnas del bucket s3 y el contenido del archivo csv que puse en pandas dataframe.
Ejemplo:
config.json
cls_config.json
cls_pandas.py
cls_s3.py
test.py
fuente