У меня есть DataFrame pandas, который я хочу загрузить в новый файл CSV. Проблема в том, что я не хочу сохранять файл локально перед переносом на s3. Есть ли какой-нибудь метод, например to_csv, для прямой записи фрейма данных в s3? Я использую boto3.
Вот что у меня есть на данный момент:
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 для получения дополнительной информации.Ответы:
Ты можешь использовать:
источник
TypeError: unicode argument expected, got 'str'
ошибка при использованииStringIO
. Я использовал,BytesIO
и он работал отлично. Примечание: это было в Python 2.7bucket
объект? как ты это создал?bucket
это место, где вы храните объекты на S3. Код предполагает, что вы уже создали место назначения (думаю: каталог), где это хранить. См. Документы S3Вы можете напрямую использовать путь S3. Я использую Pandas 0.24.1
Release Note:
источник
NoCredentialsError: Unable to locate credentials
. Какие-либо предложения?NotImplementedError: Text mode not supported, use mode='wb' and manage bytes
. какие-либо предложения?Мне нравится s3fs который позволяет использовать s3 (почти) как локальную файловую систему.
Ты можешь сделать это:
s3fs
поддерживает толькоrb
иwb
режимы открытия файла, поэтому я и сделал этоbytes_to_write
.источник
s3fs
, похоже, не поддерживает режим добавления.Это более свежий ответ:
Проблема с StringIO в том, что он разъедает вашу память. С помощью этого метода вы передаете файл в s3, а не конвертируете его в строку, а затем записываете в s3. Хранение фрейма данных pandas и его строковой копии в памяти кажется очень неэффективным.
Если вы работаете в момент времени ec2, вы можете назначить ему роль IAM, чтобы разрешить запись в s3, поэтому вам не нужно передавать учетные данные напрямую. Однако вы также можете подключиться к корзине, передав учетные данные в
S3FileSystem()
функции. См. Документацию: https://s3fs.readthedocs.io/en/latest/источник
to_csv()
. кажется более чистой реализацией.botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
... Я даже сделал сегмент ПУБЛИЧНОЕ ЧТЕНИЕ, и я добавил следующие действия под моим конкретным пользователем IAM учетной записи в политику"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());
Если вы передадите
None
первый аргумент,to_csv()
данные будут возвращены в виде строки. Оттуда это простой шаг, чтобы загрузить его на S3 за один раз.Также должна быть возможность передать
StringIO
объектto_csv()
, но с использованием строки будет проще.источник
None
кto_csv()
возвращенной строке и использовать ее, чем создатьStringIO
объект и затем прочитать данные обратно.Я обнаружил, что это можно сделать с помощью
client
также, а не толькоresource
.источник
Вы также можете использовать AWS Data Wrangler :
Обратите внимание, что он будет разделен на несколько частей, поскольку загружает его параллельно.
источник
поскольку вы используете
boto3.client()
, попробуйте:источник
Я нашел очень простое решение, которое, похоже, работает:
Надеюсь, это поможет !
источник
Я прочитал csv с двумя столбцами из ведра s3 и содержимое файла csv, которое я поместил в pandas dataframe.
Пример:
config.json
cls_config.json
cls_pandas.py
cls_s3.py
test.py
источник