web-dev-qa-db-fra.com

Comment obtenir les bibliothèques Python dans pyspark?

Je veux utiliser les bibliothèques matplotlib.bblpath ou shapely.geometry dans pyspark.

Lorsque j'essaie d'importer l'un d'eux, j'obtiens l'erreur ci-dessous:

>>> from shapely.geometry import polygon
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ImportError: No module named shapely.geometry

Je sais que le module n'est pas présent, mais comment ces packages peuvent-ils être apportés à mes bibliothèques pyspark?

11
thenakulchawla

Dans le contexte Spark, essayez d'utiliser:

SparkContext.addPyFile("module.py")  # also .Zip

, citant les docs :

Ajoutez une dépendance .py ou .Zip pour toutes les tâches à exécuter sur ce SparkContext à l'avenir. Le chemin d'accès peut être soit un fichier local, un fichier en HDFS (ou d'autres systèmes de fichiers pris en charge par Hadoop), soit un URI HTTP, HTTPS ou FTP.

16
armatita

C'est ainsi que je l'ai fait fonctionner dans notre cluster AWS EMR (il devrait être le même dans tout autre cluster également). J'ai créé le script Shell suivant et l'ai exécuté comme une action d'amorçage:

#!/bin/bash
# shapely installation
wget http://download.osgeo.org/geos/geos-3.5.0.tar.bz2
tar jxf geos-3.5.0.tar.bz2
cd geos-3.5.0 && ./configure --prefix=$HOME/geos-bin && make && make install
Sudo cp /home/hadoop/geos-bin/lib/* /usr/lib
Sudo /bin/sh -c 'echo "/usr/lib" >> /etc/ld.so.conf'
Sudo /bin/sh -c 'echo "/usr/lib/local" >> /etc/ld.so.conf'
Sudo /sbin/ldconfig
Sudo /bin/sh -c 'echo -e "\nexport LD_LIBRARY_PATH=/usr/lib" >> /home/hadoop/.bashrc'
source /home/hadoop/.bashrc
Sudo pip install shapely
echo "Shapely installation complete"
pip install https://pypi.python.org/packages/74/84/fa80c5e92854c7456b591f6e797c5be18315994afd3ef16a58694e1b5eb1/Geohash-1.0.tar.gz
#
exit 0

Remarque: Au lieu de s'exécuter en tant qu'actions de démarrage, ce script peut être exécuté indépendamment dans chaque nœud d'un cluster. J'ai testé les deux scénarios.

Voici un exemple de code pyspark et galbé (Spark SQL UDF) pour garantir que les commandes ci-dessus fonctionnent comme prévu:

Python 2.7.10 (default, Dec  8 2015, 18:25:23) 
[GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /__ / .__/\_,_/_/ /_/\_\   version 1.6.1
      /_/

Using Python version 2.7.10 (default, Dec  8 2015 18:25:23)
SparkContext available as sc, HiveContext available as sqlContext.
>>> from pyspark.sql.functions import udf
>>> from pyspark.sql.types import StringType
>>> from shapely.wkt import loads as load_wkt
>>> def parse_region(region):
...     from shapely.wkt import loads as load_wkt
...     reverse_coordinate = lambda coord: ' '.join(reversed(coord.split(':')))
...     coordinate_list = map(reverse_coordinate, region.split(', '))
...     if coordinate_list[0] != coordinate_list[-1]:
...         coordinate_list.append(coordinate_list[0])
...     return str(load_wkt('POLYGON ((%s))' % ','.join(coordinate_list)).wkt)
... 
>>> udf_parse_region=udf(parse_region, StringType())
16/09/06 22:18:34 WARN ObjectStore: Version information not found in metastore. Hive.metastore.schema.verification is not enabled so recording the schema version 1.2.0
16/09/06 22:18:34 WARN ObjectStore: Failed to get database default, returning NoSuchObjectException
>>> df = sqlContext.sql('select id, bounds from <schema.table_name> limit 10')
>>> df2 = df.withColumn('bounds1', udf_parse_region('bounds'))
>>> df2.first()
Row(id=u'0089d43a-1b42-4fba-80d6-dda2552ee08e', bounds=u'33.42838509594465:-119.0533447265625, 33.39170168789402:-119.0203857421875, 33.29992542601392:-119.0478515625', bounds1=u'POLYGON ((-119.0533447265625 33.42838509594465, -119.0203857421875 33.39170168789402, -119.0478515625 33.29992542601392, -119.0533447265625 33.42838509594465))')
>>> 

Merci, Hussain Bohra

7
Hussain Bohra

Est-ce sur autonome (c'est-à-dire ordinateur portable/bureau) ou dans un environnement de cluster (par exemple AWS EMR)?

  1. Si sur votre ordinateur portable/de bureau, pip install shapely devrait très bien fonctionner. Vous devrez peut-être vérifier vos variables d'environnement pour votre python environnement (s) par défaut. Par exemple, si vous utilisez généralement Python 3 mais utilisez Python 2 pour pyspark, alors vous n'auriez pas bien fait pour pyspark.

  2. Si dans un environnement de cluster tel que dans AWS EMR, vous pouvez essayer:

    import os
    
    def myfun(x):`
            os.system("pip install shapely")
            return x
    rdd = sc.parallelize([1,2,3,4]) ## assuming 4 worker nodes
    rdd.map(lambda x: myfun(x)).collect() 
    ## call each cluster to run the code to import the library
    

"Je sais que le module n'est pas présent, mais je veux savoir comment ces packages peuvent être introduits dans mes bibliothèques pyspark."

Sur EMR, si vous souhaitez que pyspark soit pré-préparé avec les autres bibliothèques et configurations que vous souhaitez, vous pouvez utiliser une étape bootstrap pour effectuer ces ajustements. À part cela, vous ne pouvez pas " ajouter "une bibliothèque à pyspark sans compiler Spark in Scala (ce qui serait difficile à faire si vous n'êtes pas averti avec SBT).

2
Jon