「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>Apache Spark]]

*目次 [#k30dfef7]
#contents

*概要 [#r180bc95]
[[.NET for Apache Spark>Apache Spark#a2ce8cf5]]のチュートリアル用環境で動作したので。
-[[Apache Spark]]の[[Python]]言語バインディング
-[[.NET for Apache Spark>Apache Spark#a2ce8cf5]]のチュートリアル用環境で動作したので。

*詳細 [#i5025fa2]

**Jupyter Notebook [#y2664b01]
-Jupyter Notebookドキュメントを作成・共有するためのウェブアプリケーション
-プログラムコード、Markdownテキスト、数式、図式等を含むことができる。
**Notebook系 [#xa89d7e4]
[[Apache Spark]]の特性上、インタラクティブな環境の方が習得が捗る。

-そのため、以下のように表現される。
--PythonなどをWebブラウザ上で記述・実行できる統合開発環境
--ブラウザ上で Python やその他のプログラミング言語のプログラムを~
実行したり、実行した結果を保存したり共有したりすることができるツール
***[[Jupyter Notebook]] [#y2664b01]

-参考
--Project Jupyter - Wikipedia~
https://ja.wikipedia.org/wiki/Project_Jupyter
***[[Azure Databricks>#p629aafe]] [#f0ad6acf]

**チュートリアル [#n212eaf0]

***on Docker [#ffe40eef]
-ローカルでもできそうだったが、手軽そうな[[Docker]]をチョイス。

-以下、[[Qiitaの「Apache Spark を Jupyter Notebook で試す (on ローカル Docker」>#f615d0ec]]を参考にした。

-[[Docker]]前提で(ここでは、[[Docker for Windows>https://techinfoofmicrosofttech.osscons.jp/index.php?Docker%20for%20Windows]]を使用した)

--環境のコンテナを

---docker run する場合
 docker run -it -p 8888:8888 jupyter/pyspark-notebook

---docker-compose を使う場合~
・docker-compose.yaml
 version: '3'
 services:
   notebook:
     image: jupyter/pyspark-notebook
     ports:
       - '8888:8888'
     environment:
       - GRANT_SUDO=yes
       - TZ=Asia/Tokyo
     volumes:
       - ./work:/home/jovyan/work
       - ./path:/home/jovyan/path
~
・docker-compose up
 >docker-compose up -d
※ /jovyanをマウントすると、Kernel errorになる。~
  多分、jovyan直下に必要なファイルが存在している。


-最後に表示されたURLにブラウザからアクセスする。
 [C 03:39:12.997 NotebookApp]
 To access the notebook, open this file in a browser:
     file:///home/jovyan/.local/share/jupyter/runtime/nbserver-7-open.html
 Or copy and paste one of these URLs:
     http://xxxxx:8888/?token=xxxxx
     or http://127.0.0.1:8888/?token=xxxxx

-[[Jupyter Notebook>#y2664b01]]が表示されるので、~
New から Notebook: Python3 を選択し Notebook を開く。

-ハロー・ワールド風

--「In []:」に以下を貼り付けて RUN [▶] を押下する。
 from pyspark.sql import SparkSession
 spark: SparkSession = SparkSession.builder.appName("SimpleApp").getOrCreate()
 # do something to prove it works
 spark.sql('SELECT "Test" as c1').show()

--以下のような結果が表示され、動作が確認できる。
 +----+
 |  c1|
 +----+
 |Test|
 +----+

--Jupyter Notebookでは、Session?が維持されるので、~
以降の処理で、SparkSessionを再度定義する必要は無い。

-Tuple&Listの二次元表からDataFrameを生成する。

--「In []:」に以下を貼り付けて RUN [▶] を押下する。
 from typing import List, Tuple
 from pyspark.sql import SparkSession
 from pyspark.sql import DataFrame
 from pyspark.sql.types import StructField, StructType, StringType, IntegerType
 
 Trainer = Tuple[int, str, str, int]
 trainers: List[Trainer] = [
     (1, 'サトシ', 'male',   10),
     (2, 'シゲル', 'male',   10),
     (3, 'カスミ', 'female', 12),
 ]
 
 trainers_schema = StructType([
     StructField('id',      IntegerType(), True),
     StructField('name',    StringType(),  True),
     StructField('gender',  StringType(),  True),
     StructField('age',     IntegerType(), True),
 ])
 
 trainers_df: DataFrame = spark.createDataFrame(
     spark.sparkContext.parallelize(trainers),
     trainers_schema
 )
 
 trainers_df.show()

--以下のような結果が表示され、動作が確認できる。
 +---+------+------+---+
 | id|  name|gender|age|
 +---+------+------+---+
 |  1|サトシ|  male| 10|
 |  2|シゲル|  male| 10|
 |  3|カスミ|female| 12|
 +---+------+------+---+

-DataFrame を Row の list で返す。

--前述のtrainers_df.show()以降に以下を追記して RUN [▶] を押下する。
 result = trainers_df.collect()
 print(result)

--以下のような結果が表示され、動作が確認できる。
 [Row(id=1, name='サトシ', gender='male', age=10), Row(id=2, name='シゲル', gender='male', age=10), Row(id=3, name='カスミ', gender='female', age=12)]

-入出力

--CSV出力

---前述のtrainers_df.show()以降に以下を追記して RUN [▶] を押下する。
 trainers_df.coalesce(1).write.mode('overwrite').csv("path/to/output.csv")

---CSV出力の確認~
・コンテナに入って確認する。
 >docker ps
 CONTAINER ID   IMAGE                        COMMAND CREATED STATUS PORTS NAMES
 xxxxxxxxxxxx   jupyter/pyspark-notebook...
 ...
 
 >docker exec -i -t xxxxxxxxxxxx /bin/bash
 ... /home/jovyan/path/to を探してみると、出力を確認できる。
~
・docker-compose.yamlのvolumesに指定した~
 フォルダを探してみると、出力を確認できる。~
~
・[[Jupyter Notebook>#y2664b01]](Files)からも確認できる。~
 http://127.0.0.1:8888/tree#notebooks

--CSV入力~
上記ファイルを入力する方法は...、

---「In []:」に以下を貼り付けて RUN [▶] を押下する。
 from pyspark.sql import SparkSession
 from pyspark.sql import DataFrame
 from pyspark.sql.types import StructField, StructType, StringType, IntegerType
 
 trainers_schema = StructType([
     StructField('id',      IntegerType(), True),
     StructField('name',    StringType(),  True),
     StructField('gender',  StringType(),  True),
     StructField('age',     IntegerType(), True),
 ])
 
 trainers_df: DataFrame = spark.read.format("csv")\
     .options(header="false")\
     .load("path/to/output.csv", schema=trainers_schema)
 
 trainers_df.show()

---以下のような結果が表示され、動作が確認できる。
 +---+------+------+---+
 | id|  name|gender|age|
 +---+------+------+---+
 |  1|サトシ|  male| 10|
 |  2|シゲル|  male| 10|
 |  3|カスミ|female| 12|
 +---+------+------+---+

-以下は、[[Spark SQLとDataFrame API>Spark SQL]]を使用した操作。

--前述のtrainers_df.show()以降に以下を追記して RUN [▶] を押下する。

---Spark SQLを使用する。
 trainers_df.createOrReplaceTempView('trainers');
 male_trainers_df = spark.sql('''
   SELECT *
   FROM   trainers
   WHERE  gender = 'male'
 ''')
 male_trainers_df.show()
※ トリプル・クォーテーションは改行を扱える。

---DataFrame APIを使用する。
 male_trainers_df = trainers_df.filter(trainers_df['gender'] == 'male')
 male_trainers_df.show()

--以下のような結果が表示され、動作が確認できる。
 +---+------+------+---+
 | id|  name|gender|age|
 +---+------+------+---+
 |  1|サトシ|  male| 10|
 |  2|シゲル|  male| 10|
 |  3|カスミ|female| 12|
 +---+------+------+---+
 
 +---+------+------+---+
 | id|  name|gender|age|
 +---+------+------+---+
 |  1|サトシ|  male| 10|
 |  2|シゲル|  male| 10|
 +---+------+------+---+

-以下は、ユーザー定義関数(UDF)を使用した操作。

--前述に

---ユーザー定義関数(UDF)のimportを追加し、
 from pyspark.sql.functions import udf

---trainers_df.show()以降に以下を追記して RUN [▶] を押下する。
 @udf(StringType())
 def name_with_suffix(name: str, gender: str) -> str:
   return name + {'male': 'くん', 'female': 'さん'}.get(gender, '氏')
 
 spark.udf.register('name_with_suffix', name_with_suffix)
 
 dearest_trainers = spark.sql('''
   SELECT name_with_suffix(name, gender) as hoge
   FROM   trainers
 ''')
 
 dearest_trainers.show()

--以下のような結果が表示され、動作が確認できる。
 +---+------+------+---+
 | id|  name|gender|age|
 +---+------+------+---+
 |  1|サトシ|  male| 10|
 |  2|シゲル|  male| 10|
 |  3|カスミ|female| 12|
 +---+------+------+---+
 
 +----------+
 |      hoge|
 +----------+
 |サトシくん|
 |シゲルくん|
 |カスミさん|
 +----------+

***[[on Azure Databricks>https://techinfoofmicrosofttech.osscons.jp/index.php?Azure%20Databricks%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB#r15035b9]] [#p629aafe]
リンク先で、Databricksで動かしてみる。

*参考 [#z4b7048e]

-PySpark環境構築メモ - Smile Engineering Blog~
https://smile-jsp.hateblo.jp/entry/2020/05/07/012432

-WindowsでSpark(PySpark)環境をつくる - goodbyegangsterのブログ~
https://goodbyegangster.hatenablog.com/entry/2018/06/27/022915

-Jupyter Notebookの使い方 | Python入門~
https://www.javadrive.jp/python/jupyter-notebook/

**EnsekiTT Blog [#z408f56e]
-Dockerでデータ分析環境を作るためにJupyter Docker Stacksを使ってみた話~
https://ensekitt.hatenablog.com/entry/2018/06/29/200000
-うっかりコンテナを削除しても大丈夫なようにdocker-composeを使うことにした話~
https://ensekitt.hatenablog.com/entry/2018/07/01/200000
>タイトルからでは解り難いが、jupyter/datascience-notebookの~
/home/jovyan/ディレクトリをdocker-composeでマウントする内容。

**CUBE SUGAR CONTAINER [#m977e9b5]
-PySpark: 時刻と文字列を相互に変換する (DataFrame / Spark SQL)~
https://blog.amedama.jp/entry/2018/01/29/212711
-PySpark: Jupyter Notebook からローカルの PySpark ドライバを操作する~
https://blog.amedama.jp/entry/2018/01/29/215458
-PySpark の UDF (User Defined Function) を試す~
https://blog.amedama.jp/entry/2018/01/31/210755
-PySpark の DataFrame を SparkSQL で操作する~
https://blog.amedama.jp/entry/2018/03/03/173257
-PySpark のスクリプトファイルで引数を扱う~
https://blog.amedama.jp/entry/2018/03/17/113516

**Qiita [#f615d0ec]
-Ubuntu18.04 (WSL)でpyspark+jupyterの環境を手早く作る~
https://qiita.com/gaborotta/items/0d324f58ae3f0149db2a

-Apache Spark を Jupyter Notebook で試す (on ローカル Docker~
https://qiita.com/mangano-ito/items/dac5582a331d40a484ad

-Jupyter NotebookでのpySparkコードサンプル~
https://qiita.com/kazurof/items/0e8e46771cd845b7edbb

-【PySpark】dataframe操作サンプルコード集~
https://qiita.com/YujiHamada3/items/0220bb68efb5c1e6ef62


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS