Comment lire une liste de parquet fichiers à partir de S3 comme les pandas dataframe à l'aide de pyarrow?
J'ai un hacky façon de réaliser cela à l'aide de boto3
(1.4.4), pyarrow
(0.4.1) et pandas
(0.20.3).
Tout d'abord, je peux lire un seul parquet fichier localement comme ceci:
import pyarrow.parquet as pq
path = 'parquet/part-r-00000-1e638be4-e31f-498a-a359-47d017a0059c.gz.parquet'
table = pq.read_table(path)
df = table.to_pandas()
Je peux aussi lire un répertoire de parquet localement les fichiers comme ceci:
import pyarrow.parquet as pq
dataset = pq.ParquetDataset('parquet/')
table = dataset.read()
df = table.to_pandas()
À la fois le travail comme un charme. Maintenant, je veux atteindre le même à distance aux fichiers stockés dans un compartiment S3. J'espérais que quelque chose de ce genre:
dataset = pq.ParquetDataset('s3n://dsn/to/my/bucket')
Mais il ne le fait pas:
OSError: Passed non-file path: s3n://dsn/to/my/bucket
Après la lecture de pyarrow de la documentation à fond, cela ne semble pas possible pour le moment. Alors je suis venu avec la solution suivante:
Lecture d'un fichier unique à partir de S3 et de l'obtention des pandas dataframe:
import io
import boto3
import pyarrow.parquet as pq
buffer = io.BytesIO()
s3 = boto3.resource('s3')
s3_object = s3.Object('bucket-name', 'key/to/parquet/file.gz.parquet')
s3_object.download_fileobj(buffer)
table = pq.read_table(buffer)
df = table.to_pandas()
Et voici mon hacky, de ne pas très optimisé, la solution pour créer une pandas dataframe à partir d'un S3 chemin d'accès au dossier:
import io
import boto3
import pandas as pd
import pyarrow.parquet as pq
bucket_name = 'bucket-name'
def download_s3_parquet_file(s3, bucket, key):
buffer = io.BytesIO()
s3.Object(bucket, key).download_fileobj(buffer)
return buffer
client = boto3.client('s3')
s3 = boto3.resource('s3')
objects_dict = client.list_objects_v2(Bucket=bucket_name, Prefix='my/folder/prefix')
s3_keys = [item['Key'] for item in objects_dict['Contents'] if item['Key'].endswith('.parquet')]
buffers = [download_s3_parquet_file(s3, bucket_name, key) for key in s3_keys]
dfs = [pq.read_table(buffer).to_pandas() for buffer in buffers]
df = pd.concat(dfs, ignore_index=True)
Est-il un meilleur moyen pour y parvenir? Peut-être une sorte de connecteur pour les pandas à l'aide de pyarrow? Je voudrais éviter d'utiliser pyspark
, mais si il n'y a pas d'autre solution, alors je le prendrais.
OriginalL'auteur Diego Mora Cespedes | 2017-07-11
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser le
s3fs
module proposé par yjk21. Cependant, comme le résultat de l'appel d'ParquetDataset vous obtiendrez un pyarrow.parquet.ParquetDataset objet. Pour obtenir les Pandas DataFrame vous aurez plutôt souhaitez appliquer.read_pandas().to_pandas()
:Votre message d'erreur est malheureusement tronquée, donc je ne vois pas le répertoire mentionné. Mais on pourrait faire une supposition. En effet, lorsque la partitionné parquet fichiers sont stockés pour S3, ils sont généralement d'abord écrit "_temporary" répertoire. Si ce répertoire n'est pas vide, alors c'est un signe clair que S3-emplacement contient incomplète (cassé) de données.
OriginalL'auteur vak
Vous pouvez utiliser s3fs de dask qui met en œuvre un système de fichiers de l'interface pour les s3. Ensuite, vous pouvez utiliser le système de fichiers argument de ParquetDataset comme suit:
OriginalL'auteur yjk21
Il peut être fait à l'aide de boto3 aussi bien sans l'utilisation de pyarrow
AttributeError: 's3.Object' object has no attribute 'download_fileobj'
.OriginalL'auteur oya163
Probablement le moyen le plus facile à lire parquet de données sur le cloud dans dataframes est d'utiliser dask.dataframe de cette façon:
dask.dataframe
peut lire à partir de Google Cloud Storage, Amazon S3, Hadoop système de fichiers et plus encore!OriginalL'auteur Rich Signell
Merci! Votre question m'a dit beaucoup de choses. C'est la façon dont je le fais maintenant avec
pandas
(0.21.1), qui feront appelpyarrow
, etboto3
(1.3.1).Ensuite, vous pouvez lire plusieurs parquets en vertu d'un dossier de S3 par
(On peut simplifier ce code beaucoup je suppose.)
OriginalL'auteur Louis Yang