Je travaille avec pandas et avec spark dataframes. Les dataframes sont toujours très gros (> 20 Go) et le standard spark = les fonctions ne sont pas suffisantes pour ces tailles. Actuellement, je convertis mon pandas dataframe en un spark dataframe comme ceci:
dataframe = spark.createDataFrame(pandas_dataframe)
Je fais cette transformation car avec spark l'écriture de cadres de données sur hdfs est très facile:
dataframe.write.parquet(output_uri, mode="overwrite", compression="snappy")
Mais la transformation échoue pour les trames de données supérieures à 2 Go. Si je transforme un spark dataframe en pandas je peux utiliser pyarrow:
// temporary write spark dataframe to hdfs
dataframe.write.parquet(path, mode="overwrite", compression="snappy")
// open hdfs connection using pyarrow (pa)
hdfs = pa.hdfs.connect("default", 0)
// read parquet (pyarrow.parquet (pq))
parquet = pq.ParquetDataset(path_hdfs, filesystem=hdfs)
table = parquet.read(nthreads=4)
// transform table to pandas
pandas = table.to_pandas(nthreads=4)
// delete temp files
hdfs.delete(path, recursive=True)
Ceci est une conversion rapide de spark à pandas et cela fonctionne également pour les trames de données supérieures à 2 Go. Je n'ai pas encore trouvé de moyen de le faire l'autre) Cela signifie avoir un pandas dataframe que je transforme en spark avec l'aide de pyarrow. Le problème est que je ne peux vraiment pas trouver comment écrire un = pandas dataframe to hdfs.
Ma pandas version: 0.19.0
Cela signifie avoir un cadre de données pandas que je transforme en spark à l'aide de pyarrow.
pyarrow.Table.fromPandas
est la fonction que vous recherchez:
Table.from_pandas(type cls, df, bool timestamps_to_ms=False, Schema schema=None, bool preserve_index=True) Convert pandas.DataFrame to an Arrow Table
import pyarrow as pa
pdf = ... # type: pandas.core.frame.DataFrame
adf = pa.Table.from_pandas(pdf) # type: pyarrow.lib.Table
Le résultat peut être écrit directement sur Parquet/HDFS sans passer de données via Spark:
import pyarrow.parquet as pq
fs = pa.hdfs.connect()
with fs.open(path, "wb") as fw
pq.write_table(adf, fw)
Voir aussi
pyarrow
.Spark notes :
De plus, depuis Spark 2.3 (maître actuel), Arrow est pris en charge directement dans createDataFrame
( SPARK-20791 - Utilisez Apache Arrow pour améliorer Spark createDataFrame de Pandas. DataFrame ). Il utilise SparkContext.defaultParallelism
Pour calculer le nombre de morceaux afin que vous puissiez facilement contrôler la taille des lots individuels.
Enfin, defaultParallelism
peut être utilisé pour contrôler le nombre de partitions générées à l'aide du _convert_from_pandas
Standard, réduisant ainsi la taille des tranches à quelque chose de plus gérable.
Malheureusement, il est peu probable que ceux-ci résolvent vos problèmes de mémoire actuels . Les deux dépendent de parallelize
, donc stockez toutes les données dans la mémoire du nœud du pilote. Passer à Arrow ou ajuster la configuration ne peut qu'accélérer le processus ou résoudre les limitations de taille de bloc.
Dans la pratique, je ne vois aucune raison de passer à Spark ici, tant que vous utilisez local Pandas DataFrame
comme entrée. Le goulot d'étranglement le plus grave dans ce scénario est les E/S réseau du pilote et la distribution des données ne résoudra pas cela.
Une autre façon est de convertir votre pandas dataframe en spark dataframe (en utilisant pyspark) et de l'enregistrer dans hdfs avec la commande save. Example
df = pd.read_csv("data/as/foo.csv")
df[['Col1', 'Col2']] = df[['Col2', 'Col2']].astype(str)
sc = SparkContext(conf=conf)
sqlCtx = SQLContext(sc)
sdf = sqlCtx.createDataFrame(df)
Ici astype
change le type de votre colonne de object
à string
. Cela vous évite une exception autrement levée car spark n'a pas pu comprendre pandas type object
. Mais assurez-vous que ces colonnes sont vraiment de type chaîne.
Maintenant, pour enregistrer votre df dans hdfs:
sdf.write.csv('mycsv.csv')
De https://issues.Apache.org/jira/browse/SPARK-6235
Prise en charge de la parallélisation des données R d'une taille supérieure à 2 Go
est résolu.
De https://pandas.pydata.org/pandas-docs/stable/r_interface.html
Conversion de DataFrames en objets R
vous pouvez convertir un pandas dataframe en un R data.frame
Alors peut-être que la transformation pandas -> R -> Spark -> hdfs?