Saya memiliki DataFrame panda yang ingin saya unggah ke file CSV baru. Masalahnya adalah saya tidak ingin menyimpan file secara lokal sebelum mentransfernya ke s3. Apakah ada metode seperti to_csv untuk menulis dataframe ke s3 secara langsung? Saya menggunakan boto3.
Inilah yang saya miliki sejauh ini:
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 untuk info lebih lanjut.Jawaban:
Kamu bisa memakai:
sumber
TypeError: unicode argument expected, got 'str'
kesalahan saat menggunakanStringIO
. Saya menggunakanBytesIO
dan bekerja dengan baik. Catatan: ini menggunakan Python 2.7bucket
objek? bagaimana kamu membuatnya?bucket
adalah tempat Anda menyimpan objek di S3. Kode mengasumsikan Anda telah membuat tujuan (pikirkan: direktori) tempat menyimpan ini. Lihat dokumen S3Anda dapat langsung menggunakan jalur S3. Saya menggunakan Pandas 0.24.1
Catatan Rilis:
sumber
NoCredentialsError: Unable to locate credentials
. Ada saran?NotImplementedError: Text mode not supported, use mode='wb' and manage bytes
. ada saran?Saya suka s3fs yang memungkinkan Anda menggunakan s3 (hampir) seperti sistem file lokal.
Kamu bisa melakukan ini:
s3fs
hanya mendukungrb
danwb
mode membuka file, itulah mengapa saya melakukanbytes_to_write
hal ini .sumber
s3fs
sepertinya tidak mendukung mode penambahan .Ini adalah jawaban yang lebih mutakhir:
Masalah dengan StringIO adalah ia akan menggerogoti memori Anda. Dengan metode ini, Anda mengalirkan file ke s3, daripada mengubahnya menjadi string, lalu menulisnya menjadi s3. Memegang bingkai data panda dan salinan stringnya di memori tampaknya sangat tidak efisien.
Jika Anda bekerja dalam ec2 instan, Anda dapat memberikan peran IAM untuk mengaktifkan penulisannya ke s3, sehingga Anda tidak perlu memberikan kredensial secara langsung. Namun, Anda juga dapat terhubung ke bucket dengan meneruskan kredensial ke
S3FileSystem()
fungsi tersebut. Lihat dokumentasinya: https://s3fs.readthedocs.io/en/latest/sumber
to_csv()
. sepertinya implementasi yang lebih bersih.botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
... Saya bahkan telah membuat keranjang PUBLIC READ dan saya telah menambahkan Tindakan berikut, di bawah akun khusus pengguna IAM, di Kebijakan 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());
Jika Anda lolos
None
sebagai argumen pertama keto_csv()
, data akan dikembalikan sebagai string. Dari sana, langkah mudah untuk mengunggahnya ke S3 dalam sekali jalan.Itu juga harus memungkinkan untuk mengirimkan
StringIO
objek keto_csv()
, tetapi menggunakan string akan lebih mudah.sumber
None
keto_csv()
dan menggunakan string kembali daripada untuk membuatStringIO
objek dan kemudian membaca data mundur.Saya menemukan ini dapat dilakukan dengan menggunakan
client
juga dan tidak hanyaresource
.sumber
Anda juga dapat menggunakan AWS Data Wrangler :
Perhatikan bahwa itu akan dibagi menjadi beberapa bagian karena mengunggahnya secara paralel.
sumber
karena Anda menggunakan
boto3.client()
, coba:sumber
Saya menemukan solusi yang sangat sederhana yang tampaknya berhasil:
Semoga membantu!
sumber
Saya membaca csv dengan dua kolom dari ember s3, dan isi file csv saya masukkan ke dalam pandas dataframe.
Contoh:
config.json
cls_config.json
cls_pandas.py
cls_s3.py
test.py
sumber