SAS開発者向けDatabricksとPySparkのご紹介

[Introduction to Databricks and PySpark for SAS Developers \- The Databricks Blog](https://databricks.com/blog/2021/12/07/introduction-to-databricks-and-pyspark-for-sas-developers.html)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

> これは、DatabricksとWiseWithDataの共著です。[WiseWithData](https://www.wisewithdata.com/our-leadership-team/)の創始者かつプレジデントのIan J. Ghent、Head of Pre-Sales Solutions R&DのBryan Chuinkam、Migration Solutions R&DのBan (Mike) Sunに感謝の意を表します。

SAS®ドリブンのデータ、分析ワークロードの日々から、技術は長い道を歩んできました。[レイクハウス](https://qiita.com/taka_yayoi/items/438f762126f57868aa35)アーキテクチャは、異なるユースケース(データサイエンス、機械学習、リアルタイム分析、古典的なBI、データウェアハウス)に対応するためにデータチームが単一のデータコピーのあらゆるタイプのデータ(構造化、準構造化、非構造化データ)の処理を可能とします。パフォーマンスと機能はシンプルさと組み合わされ、現在では世界で比類のないプラットフォームを作り出しています。PythonやApache Spark™のようなオープンソース技術は、主にこれらがシンプルかつアクセスが容易なことから、データエンジニアやデータサイエンティストにとってNo.1の言語となっています。

多くのSASユーザーは、自身のスキルセットをモダン化するための道のりに大胆に踏み出しています。DatabricksとPySparkはシンプルに学習できるように設計されていますが、SASにフォーカスした経験豊富な実践者にとっては学習曲線が存在し得ます。しかし、SAS開発者コミュニティにとって良いニュースは、Databricksはオープンかつシンプルなプラットフォームアーキテクチャを具現化し、モダンなデータ&AIなクラウドプラットフォームでのソリューション開発を行いたいと考える誰に対しても簡単なものにしているということです。本書では、分析プログラミングの世界におけるいくつかの新旧コンポーネントマッピングに触れます。

# 共通する土台を見出す

これら全ての違いに対して、SASとDatabricksは特筆すべきいくつかの類似点があります。両方とも、徹底的に統合エンタープライズ基準のプラットフォームとなるように設計されています。両方とも、分析者がSQLとより柔軟性のあるプログラミングパラダイムを組み合わせることを可能としています。両方ともビルトインのトランスフォーメーションとデータの要約機能を備えています。両方とも線形回帰、ロジスティック回帰、決定木、ランダムフォレスト、クラスタリングのようなハイエンドの分析機能をサポートしています。また、両方とも背後のデータソースの詳細を抽象化するセマンティックデータレイヤーを備えています。これらの共有コンセプトの詳細を見ていきましょう。

## SASのDATAステップ vs データフレーム

SASのDATAステップはおそらくSAS言語で最もパワフルな機能でしょう。これを用いることで、シンプルに条件文、ループビジネスロジックと共に、union、join、フィルタリング、列の追加、削除、変更できる能力を手にすることができます。熟達したSAS開発者は、自身のコードを最適化し、I/Oを回避するために膨大なDATAステップパイプラインを構築するためにこれを活用します。

PySparkのデータフレームAPIはほとんどこれらと同じ機能を備えています。多くのユースケースにおいて、データフレームパイプラインでは、ほとんど同じ方法で同じデータ処理パイプラインを表現することができます。最も重要なこととして、データフレームは(並列度を管理する必要なしに)お使いのクラスターで並列実行されるので非常に高速でスケーラブルです。

**サンプルSASコード**

```sas:SAS
data df1;
    set df2;
    x = 1;
	    run;
```

**サンプルPySparkコード**

```py:Python
data df1;
    df1 = (
    df2
    .withColumn('x', lit(1))
)
```

## SASのPROC SQL vs SparkSQL

業界標準のSQLは分析言語ではあまり支配的ではありません。ほぼ全てのツールでにサポートは限定的です。SASにおいては、PROC SQLと呼ばれる異なるツールを使ってSQLを使用し、SASを知らない多くの人にとって馴染みのある方法でSASのデータソースとインタラクションすることができます。これは、橋渡し、あるいは多くの人が理解できる共通言語となります。

PySparkでも、spark.sql()を呼び出すことで同じような機能を提供しており、SQLの世界に入っていくことができます。しかし、Apache Spark™を用いることで、あなたのSQLの知識を活かす能力を手にすることでき、さらに踏み込むことが可能となります。SQLの表現文法はデータフレームAPIの多くの場所でサポートされており、学習をより容易なものにしています。SQLプログラマーにとって親しみやすい別のツールが、レイクハウス上で凄まじいパフォーマンスを発揮するSQLクエリーを実行するためのSQLプログラミングエディタを提供する[Databricks SQL](https://qiita.com/taka_yayoi/items/9a4dd01962ec9023ce64)です。

**サンプルSASコード**

```sas:SAS
proc sql;
    create table sales_last_month as
    select
        customer_id
        ,sum(trans_amt) as sales_amount
    from sales.pos_sales
    group by customer_id
    order by customer_id;
quit;
```

**サンプルPySparkコード**

```py:Python
sales['sales'].createOrReplaceTempView('sales')
work['sales_last_month'] = spark.sql("""
SELECT customer_id ,
       sum(trans_amt) AS sales_amount
FROM sales
GROUP BY customer_id
ORDER BY customer_id
""")
```

## ベースのSAS Proc vs PySparkデータフレームのトランスフォーメーション

SASはビルド済みの機能の多くをプロシージャ(PROCs)にパッケージングしています。これには、データ集計やサマリー統計、データのリシェープ、インポート/エクスポートなどのようなトランスフォーメーションが含まれます。これらのPROCsは大規模なジョブでことなるステップやプロセス境界を表現します。逆に、PySparkにおける同じトランスフォーメーション処理はどこでも、データフレームパイプラインの中でさえも使用することができ、開発者に更なる柔軟性を提供します。もちろん、これをさらに異なるステップに分割することもできます。

**サンプルSASコード**

```sas:SAS
proc means data=df1 max min;
    var MSRP Invoice;
	where Make = 'Acura';
    output out = df2;
run;
```

**サンプルPySparkコード**

```py:Python
df2 = (
    df1.filter("Make = 'Acura'")
    .select("MSRP", "Invoice")
    .summary('max','min')
)
```

## 遅延実行 - SASの"run"文 vs PySparkのアクション

Sparkにおける遅延実行モデルは多くの最適化の基盤となっており、PySparkをSASよりはるかに高速なものにしています。信じるか信じないかはお任せしますが、SASでも遅延実行をサポートしています！50年以上前に設計された言語としては衝撃的です。SASを書く際には避けられない"run"文の全てを知っていますか？これらは実際のところ、PySparkのアクションに対応する彼ら自身のバージョンとなります。

SASでは、プロセスでいくつかのステップを定義することができますが、"run"が呼び出されるまでは実行されません。SASとPySparkの大きな違いは遅延実行ではなく、それらによってなされる最適化です。SASでは残念なことに、実行エンジンもまた"怠惰(lazy)"であり、適用可能な全ての最適化を無視します。このため、SASコードの遅延実行はほとんど用いられず、パフォーマンスの助けになりません。

このため、あなたが次にPySparkの遅延実行モデルに混乱したら、SASと同じであるということを思い出してください。SASの場合は誰もこの機能を使っていませんが。PySparkにおけるアクションは、SASにおけるrun文のようなものです。実際、PySparkで即時実行を起動(そして、中間結果をディスクに格納)したいのであれば、run文のようにそのためのアクションが存在します。データフレームで`.checkpoint()`を呼ぶだけです。

**サンプルSASコード**

```sas:SAS
data df1;
    set df2;
    x = 1;
run;
```

**サンプルPySparkコード**

```py:Python
df1 = (
    df2
    .withColumn('x', lit(1))
).checkpoint()
```

## 高度分析とSpark ML

過去45年間を通じて、SAS言語は統計、機械学習のためのいくつかの重要な機能を蓄積してきました。SAS/SATプロシージャは、それらの奇妙で一貫性のない文法の中に機能の大部分をパッケージしています。一方、SparkMLには、STATのモダンなユースケースの大部分カバーする機能が含まれていますが、より密接かつ一貫性のある方法で提供されます。

これら二つのパッケージで特筆すべき違いの一つは、テレメトリと診断に対する全体的なアプローチです。SASにおいては、機械学習タスクを実行する際にすべての統計的指標の完全なダンプを手に入れることができます。これは、モダンなデータサイエンティストにとっては、混乱の元となり、非効率的なものになり得ます。

特に、データサイエンティストは自身のモデルの評価には一つあるいは小規模なモデル診断情報のみを必要とします。このため、SparkMLでは、リクエストに応じてこれらの診断情報を取得できるAPIを提供することで、異なり、かつよりモジュール化されたアプローチをとっています。大規模データセットにおいては、この異なるアプローチによって、不要な統計情報の計算を回避することができ、劇的に性能を改善できる可能性があります。

また、特筆すべきこととして、PySparkのMLライブラリは並列化されたアルゴリズムであるということであり、これらはより高速なものであるということです。純粋主義者の皆様に対しては、はい、シングルスレッドのロジスティック回帰モデルが適切な場合があることも知っています。この議論を聞いたことがありますが、重要なポイントを完全に見逃しています。より高速なモデル開発は、より多くのイテレーション、実験を行えることを意味し、より優れたモデルにつながります。

**サンプルSASコード**

```sas:SAS
proc logistic data=ingots;
model NotReady = Heat Soak;
run;
```

**サンプルPySparkコード**

```py:Python
vector_assembler = VectorAssembler(inputCols=['Heat', 'Soak'], outputCol='features')
v_df = vector_assembler.transform(ingots).select(['features', 'NotReady'])
lr = LogisticRegression(featuresCol='features', labelCol='NotReady')
lr_model = lr.fit(v_df)
lr_predictions = lr_model.transform(v_df)
lr_evaluator = BinaryClassificationEvaluator(
    rawPredictionCol='rawPrediction', labelCol='NotReady')
print('Area Under ROC', lr_evaluator.evaluate(lr_predictions))
```

上のPySparkサンプルでは、入力カラム`Heat, Soak`は[VectorAssembler](https://spark.apache.org/docs/3.1.1/api/python/reference/api/pyspark.ml.feature.VectorAssembler.html#pyspark.ml.feature.VectorAssembler) APIを用いて単一の特徴量ベクトルに組み合わされています。そして、変換されたデータフレームに対して、SparkMLライブラリの[LogisticRegression](https://spark.apache.org/docs/latest/ml-classification-regression.html#logistic-regression)アルゴリズムを用いてロジスティック回帰モデルがトレーニングされます。AUCメトリックを出力するために、トレーニングモデルの予測結果と実際のラベルを入力として、[BinaryClassificationEvaluator](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.ml.evaluation.BinaryClassificationEvaluator.html)が使用されます。このモジュラーアプローチは、必要なモデルパフォーマンスメトリクスを計算する際によるコントロールを効かせることができます。

# 違い

SASとPySparkの間には多くの共通点がありますが、多くの違いも存在します。PySparkを学んでいるSASエキスパートとして、これらの違いをナビゲートをするのは非常な困難なものとなります。これらをいくつかカテゴリーにブレークダウンしていきましょう。PySparkではネイティブでは利用できないいくつかSASの機能が存在し、PySparkでは異なるツール、アプローチを必要となります。
![](https://databricks.com/wp-content/uploads/2021/12/sas-blog-img-1-1024x538.png)

## 異なるエコシステム

SASプラットフォームは追加され、内部で開発された製品の全体的なコレクションであり、多くのものが比較的うまく動作します。Databricksはオープンスタンダードの上に構築されているので、数千のツールと容易に連携することができます。いくつかのSASベースのツールと同様のユースケースで使用する、Databricksで利用可能な機能を見ていきましょう。

SAS® Data Integration Studio (DI Studio)からスタートします。複雑なメタデータ駆動モデルに支えられており、DI StudioはSASのエコシステムで重要なロールのいくつかを充当します。これは主にETLワークロード向けのプロダクションジョブフロー[オーケストレーション](https://databricks.com/jp/glossary/orchestration)を提供します。Databricksにおいては、ノートブックとジョブを用いてデータエンジニアリングパイプラインが開発、デプロイされます。データエンジニアリングタスクはApache Spark(ビッグデータETLのデファクト業界スタンダード)によって強化されます。

Databricksの[Delta Live Tables\(DLT\)](https://qiita.com/taka_yayoi/items/4062930aa26f3cd14c9f)と[ジョブオーケストレーション](https://qiita.com/taka_yayoi/items/bc77fbcf1dc30d8ff742)はレイクハウスアーキテクチャにおけるETLパイプラインの開発をさらにシンプルなものにします。DLTは、従来型の手続型の変換処理のシーケンスではなく、宣言的にETLパイプラインを作成するための信頼できるフレームワークを提供します。すなわち、ユーザーは結果に至るまで実行すべきステップを明示的に順序立てて列挙する必要なしに、パイプラインに期待する結果を記述します。DLTエンジンは計算フレームワークがこれらのプロセスを「どのように」実行すべきかをインテリジェントに見つけ出します。

DIスタジオが担う別のキーとなるロールは、データリネージュ追跡の提供です。しかし、この機能は全てを適切に設定し、手動で全てのコードノードにメタデータを入力(非常に苦痛なプロセスです)した場合にのみ適切に動作します。逆に、DLTでは生成されたパイプラインがデータセット間の依存関係を自動で捕捉し、これはアップデートの実行時にどの順序で実行するのかを決定する際、パイプラインのイベントログにリネージュ情報を記録する際に活用されます。
![](https://databricks.com/wp-content/uploads/2021/12/sas-blog-img-2-1024x538.png)

多くのデータサイエンティストはコーディング好きでありますが、何人かはポイントアンドクリックのデータマイニングツールを好みます。このような人々を指す言葉として「シチズンデータサイエンティスト」が注目を浴びており、これらのペルソナは分析でありますが、それほど技術に対して深い知識を持ってはいません。SASにおいては、コーディングなしにモデルを構築するために非常に高価なツールであるSAS® Enterprise Minerを使用します。このツールでは、ユーザーは時代遅れのユーザーインタフェースを用いることで、キーボードを使用することなしに、SASデータのサンプリング、探索、変更、モデリング、評価をすべてマウスで行うことができます。SASにおける別のポイントアンドクリックツールは、SASプログラミングとポイントアンドクリック分析の両方でもっとも人気のあるインタフェースであるSAS® Enterprise Guideです。SASの複雑な文法によって、多くの人々はSASコードを生成するためにポイントアンドクリックツールを活用し、要件に合わせてコードを修正することを好んでいます。

PySparkを用いることで、APIはよりシンプル、より一貫性のあるものとなり、ヘルパーツールの必要性は低くなります。もちろん、データサイエンスを行うモダンな方法はノートブックを用いることですが、Databricksノートブックはデータをグラフで表示するなど、ポイントアンドクリックで行うべきタスクをコーディングから分離することにおいて素晴らしい働きをしています。Databricksにおける探索的データ分析とモデル開発は、DatabricksノートブックとDatabricks MLランタイムを用いて行われます。[Databricks AutoML](https://qiita.com/taka_yayoi/items/3bf4f4e89990b299c6c9)を用いることで、ユーザーはモデルをクイックにトレーニングしデプロイするためのポイントアンドクリックの手段を手に入れることができます。Databricks AutoMLでは、新規プロジェクトの変更可能なスタート地点を提供するために[MLflowトラッキング](https://databricks.com/product/managed-mlflow)とベストプラクティスを組み合わせたベースラインモデルと編集可能、共有可能なノートブックを生成することによる「ガラスボックス」アプローチを採用しています。

最近の[8080 Labs](https://docs.bamboolib.8080labs.com/databricks)の買収により、Databricksノートブックに新たな機能が提供され、ワークスペース上でローコード/ノーコードによるデータ探索と分析が可能となります。8080 Labsの[bamboolib](https://docs.bamboolib.8080labs.com/)パッケージは、ポイントアンドクリックのユーザーアクションに対応するPythonコードを自動で生成します。

まとめると、Databricksでオープンソースの[Delta Lake](https://delta.io/)で強化される[レイクハウスアーキテクチャ](https://qiita.com/taka_yayoi/items/438f762126f57868aa35)は、データアーキテクチャをシンプルにし、データレイクに全てのデータを格納し、データに対してと直接AIやBIを実行できるようにします。
![](https://databricks.com/wp-content/uploads/2021/12/sas-blog-img-3-1024x628.jpg)

上の図では、AWSにデプロイされるDatabricksのリファレンスアーキテクチャを示しており、一つの統合されたプラットフォームを通じて全てのデータソース、ユースケース、ペルソナをサポートしています。データエンジニアは容易にApache Parquet、ORCのようなオープンファイルフォーマットとビルトインのパフォーマンス最適化、トランザクションサポート、スキーマ強制、ガバナンスの機能を使い始めることができます。

今やデータエンジニアはデータパイプラインの修理に要する時間を削減でき、ビルトインの構造化ストリーミングとDelta Lakeテーブルを用いて、ストリーミングデータに対するコアのデータ変換にフォーカスすることができます。MLはレイクハウスにおける一級市民であり、データサイエンティストはダッシュボードを共有するために再度のサンプリングやデータの移動に時間を費やす必要はありません。データ分析、オペレーション分析は、他のデータステークホルダーと共に同じデータレイヤーで作業することができ、データの分析に愛されているSQLプログラミング言語を使用することができます。

## 異なるアプローチ

これら全ての変化のため、適応すべきことがいくつか存在します。SASプログラミングの機能の多くはPySparkに存在しますが、いくつかの機能は全く異なる方法で使用しなくてはならないことを意味します。PySparkで効果を発揮できるように、適応する必要がある種のいくつかの例を説明します。

## 手続型のSAS vs オブジェクト指向のPySpark

SASにおいては、お使いのコードの大部分はDATAステップかプロシージャとなります。両方の場合において、使用する入力データセット、出力データセットを常に明示的に宣言する必要があります(例: data=dataset)。逆に、PySparkデータフレームではオブジェクト指向アプローチを採用しており、データフレームへのリファレンスは実行するメソッドにアタッチされます。多くの場合、このアプローチはより便利でモダンなプログラミングテクニックと互換性があります。しかし、オブジェクト指向プログラミングを体験したことがない人にとっては、慣れるのに時間を要するかもしれません。

**サンプルSASコード**

```sas:SAS
proc sort data=df1 out=dedup nodupkey;
by cid;
run;
```

**サンプルPySparkコード**

```py:Python
dedup=df1.dropDuplicates(['cid']).orderBy(['cid'])
```

## データのリシェイプ

SASにおいて、"proc transpose"を用いるデータリシェイプの一般的なタスクの例を見てみましょう。残念ながら、転置は単一のデータシリーズに限定されるため非常に限定的です。実践的なアプリケーションにおいては何度も呼び出す必要があり、データをまとめる必要があることを意味します。小規模なSASデータセットにおいては受け入れられるかもしれませんが、大規模なデータセットにおいては数時間の追加処理を必要とするかもしれません。この制限のため、多くのSAS開発者は自身でデータのリシェイプのテクニックを構築しており、多くの人はDATAステップとretain、array、マクロのループを組み合わせています。多くの場合、このリシェイプのためのコードは100行ものSASコードとなってしまいますが、これがSASで変換処理を実行するための最も効率的な方法なのです。

DATAステップで実行されうる低レベルオペレーションの多くはPySparkでそのまま利用することはできません。代わりに、PySparkでは複数のデータシリーズを同時にサポートする`groupBy().pivot()`トランスフォーメーションによるデータリシェイプのような一般的なタスクに対するよりシンプルなインタフェースを提供しています。

**サンプルSASコード**

```sas:SAS
proc transpose data=test out=xposed;
by var1 var2;
var x;
id y;
run
```

**サンプルPySparkコード**

```py:Python
xposed = (test
    .groupBy('var1','var2')
    .pivot('y')
    .agg(last('x'))
    .withColumn('_name_',lit('y'))
)
```

## カラム指向 vs ビジネスロジック指向

PySparkを含む多くのデータ処理システムにおいては、単一のカラムの文脈でビジネスロジックを定義することができます。一方、SASではより多い柔軟性を提供しています。ユーザーはDATAステップの中でビジネスロジックの大きなブロックを定義することができ、そのビジネスロジックの枠組みの中でカラムの値を定義することができます。このアプローチでは多彩な表現ができ柔軟性がありますが、デバッグが困難となる場合もあります。

カラム指向であるマインドセットを変えることはそれほど困難でありませんが、ある程度の時間を要します。SQLを習熟しているのであれば、非常に簡単だと思います。より問題となるのは、既存のビジネスロジックコードをカラム指向の世界に適応させるということです。いくつかのDATA捨てぷには、数千行のビジネスロジック指向のコードが含まれており、手動での翻訳は完全な悪夢となります。

**サンプルSASコード**

```sas:SAS
data output_df;
    set input_df;
    if x = 5 then do;
        a = 5;
        b = 6;
        c = 7;
    end;
    else if x = 10 then do;
        a = 10;
        b = 11;
        c = 12;
    end;
    else do;
        a = 1;
        b = -1;
        c = 0;
    end;
run;
```

**サンプルPySparkコード**

```py:Python
output_df = (
    input_df
    .withColumn('a', expr("""case
        when (x = 5) then 5
        when (x = 10) then 10
        else 1 end"""))
    .withColumn('b', expr("""case
        when (x = 5) then 6
        when (x = 10) then 11
        else -1 end"""))
    .withColumn('c', expr("""case
        when (x = 5) then 7
        when (x = 10) then 12
        else 0 end"""))
)
```

## 欠けている機能

PySparkではそのままの形では存在しない、SASのパワフルかつ重要な機能が数多く存在します。道具箱にお気に入りの道具があり、突然それがなくなった場合、新たなツールがどれだけ素敵でパワフルであるかは関係ありません。これはつまり、今でもいくつかの作業においては、信頼できる日本の胴付き鋸が用いられている理由です。PySparkによるモダン化の過程においては、これまで使っていたツールが欠けていることに遭遇するでしょうが、逃げずに読み進めて良いニュースを読んでみてください。最初に、それらが何でなぜ重要なのかを話しましょう。

## 高度なSASのDATAステップ機能

新規の行を条件に基づいて生成し、以前の行の計算結果の保持するか、埋め込まれた条件のロジックを用いて合計、小計したいという状況を考えます。これら全ては、イテレーティブなSAS DATAステップAPIで比較的シンプルになりますが、我々が信頼するPySparkデータフレームは、単に容易に操作できるような機能を具備しているだけではありません。

いくつかのデータ処理タスクでは、"行イテレーティブ"の方法で、プロセス全体を通じて完全にきめ細いコントロールを必要とします。そのようなタスクは、行が互いに完全に独立に処理することを想定しているPySparkのシェアードナッシングのMPPアーキテクチャとは互換性がありません。行の間の依存関係を取り扱うためのウィンドウ関数のように限定的なAPIしか存在しません。PySparkでこれらの問題に対するソリューションを見つけ出そうとすることは、非常にフラストレーションであり時間を浪費するものとなります。

**サンプルSASコード**

```sas:SAS
data df2;
    set df;
    by customer_id seq_num;
    retain counter;
    label = "     ";
    if first.customer_id then counter = 0;
    else counter = counter+1;
    output;
    if last.customer_id then do;
        seq_num = .;
        label = "Total";
        output;
    end;
run;
```

## カラムフォーマットとインフォーマット

SASのフォーマットはシンプルさと有用性で特筆すべきものです。一つのツールでデータの再フォーマット、際マッピング、表現を行うためのメカニズムを提供します。日付の文字列を出力するような一般的なタスクを取り扱う際にはビルトインのフォーマットは有用ですが、数値、文字列の文脈においても有用です。これらのユースケース向けにPySparkで同様なツールを利用することができます。

カスタムのフォーマットとインフォーマットのコンセプトは別の話となります。これら両方はキーバリューペアのシンプルなマッピングをサポートしますが、レンジによるマッピングとデフォルト値もサポートします。joinを用いることでワークアラウンドできるユースケースがいくつか存在しますが、SASによって提供される便利かつ簡潔な文法のフォーマットは、PySparkでは提供されません。

**サンプルSASコード**

```sas:SAS
proc format;
value prodcd
    1='Shoes'
2='Boots'
    3='Sandals'
;
run;
data sales_orders;
    set sales_orders;
    product_desc = put(product_code, prodcd.);
run;
```

## ライブラリのコンセプトとアクセスエンジン

PySparkを使っているSAS開発者から共通する不満の一つに、コアのエンドユーザーAPI(Pythonのセッションなど)に直接インテグレーションされたセマンティックデータレイヤーが欠けているということです。SASのデータライブラリのコンセプトは非常に馴染み深く浸透しており、これなしにナビゲートすることは困難です。PySparkには比較的新しいカタログAPIがありますが、ストアに対する定期的なコールバックと必要なアクセス権が必要となります。論理的なデータストアを定義し、すべてのテーブルに対するデータフレームオブジェクトを一度に取り出すシンプルな方法は存在しません。PySparkにスイッチしているSAS開発者の多くは、指先でデータベースの全てのテーブルがあるアクセスエンジンライブラリのコンセプトに慣れており、それぞれのデータベースのテーブルにアクセスするために`spark.read.jdbc`をコールすることを好みません。

**サンプルSASコード**

```sas:SAS
libname lib1 ‘path1’;
libname lib2 ‘path2’;
data lib2.dataset;
    set lib1.dataset;
run;
```

# 違いを解決する - SPROCKETランタイム

SAS言語のコンセプトの多くはもはや適切ではなく、有用でもありませんが、我々が議論した欠けている機能は本当に有用で、あるケースではそれなしに生きていくことが不可能です。これが、[WiseWithData](https://www.wisewithdata.com/sas-to-databricks-automated-migration/)がこれらの慣れ親しんだ、かつパワフルな機能をモダンプラットフォームに持ち込めるように、DatabricksとPySparkに対しする特別なプラグイン[***SPROCKETランタイム***](https://www.wisewithdata.com/sprocket-runtime-for-pyspark/)を開発した理由です。これが、WiseWithDataがSASのコードを信じられないスピードで、かつ、1対1の変換エクスペリエンスを提供しつつも、DatabricksとPySparkに自動で移行できたキーとなったパーツです。

## SPROCKETライブラリとデータベースアクセスエンジン

SPROCKETライブラリによって、SAS言語のライブラリのコンセプトのように、データソースにアクセスするためのシンプルな方法で分析をクイックに追跡できるようになります。このパワフルなSPROCKETランタイムの機能によって、データパスやJDBCコネクターに関して煩わされることなしに、1行のコードで全てのデータにアクセスできることを意味します。シンプルにライブラリを登録するだけで、全ての適切なデータフレームを利用できるようになります。

**SAS**

```sas:SAS
libname lib ‘path’;
lib.dataset
```

**SPROCKET**

```py:Python
register_library(‘lib’, ‘path’)
lib[‘dataset’]
```

## カスタムフォーマット / インフォーマット

SPROCKETランタイムを用いることで、データを変換するためにカスタムフォーマット&インフォーマットのパワーとシンプルさを活用することができます。SAS環境で行ったのと同じように、カスタムフォーマットを用いてPySparkデータフレームの中のデータを変換します。

**SAS**

```sas:SAS
proc format;
value prodcd
    1='Shoes'
    2='Boots'
    3='Sandals'
;
run;
data sales_orders;
    set sales_orders;
    product_desc = put(product_code, prodcd.);
run;
```

**SPROCKET**

```py:Python
value_formats = [
    {'fmtname': 'prodcd', 'fmttype': 'N', 'fmtvalues': [
        {'start': 1, 'label': 'Shoes'},
        {'start': 2, 'label': 'Boots'},
        {'start': 3, 'label': 'Sandals'},
    ]}]
register_formats(spark, 'work', value_formats)
work['sales_orders'] = (
    work['sales_orders']
    .transform(put_custom_format(
        'product_desc', 'product_code', ‘prodcd'))
)
```

## マクロ変数

マクロ変数はSAS言語におけるパワフルなコンセプトです。PySparkにも類似のコンセプトはいくつか存在しますが、全く同じものではありません。このため、このコンセプトをSPROCKETランタイムに持ち込み、PySparkでこれらのコンセプトを容易に活用できるようにしました。

**SAS**

```sas:SAS
%let x=1;
&x
“value_&x._1”
```

**SPROCKET**

```py:Python
set_smv(‘x’, 1)
get_smv(‘x’)
“value_{x}_1”.format(**get_smvs())
```

## 高度なSASのDATAステップと行イテレーティブ処理言語(RIPL API)

SASのDATAステップ言語の柔軟性は、SPROCKETランタイムの中でPySpark APIとして利用することができます。by-group処理、保持されたカラム、do loopやarrayを使いたいですか？RIPL APIが最良の友になります。RIPL APIは、慣れ親しんだビジネスロジック指向のデータ処理ビューを取り戻します。Pythonの中で慣れ親しんだif/else条件ブロックの中にビジネスロジックを表現することができます。あなたが知知っていて愛している機能の全てを、PySparkのパフォーマンス、スケーラビリティ、Pythonの使いやすさと組み合わせることができます。

**SAS**

```sas:SAS
data df2;
    set df;
    by customer_id seq_num;
    retain counter;
    label = "     ";
    if first.customer_id then counter = 0;
    else counter = counter+1;
    output;
    if last.customer_id then do;
        seq_num = .;
        label = "Total";
        output;
    end;
run;
```

**SPROCKET – RIPL API**

```py:Python
def ripl_logic():
    rdv['label'] = '     '
    if rdv['_first_customer_id'] > 0:
        rdv['counter'] = 0
    else:
 rdv['counter'] = rdv['counter']+1
        output()
    if rdv['_last_customer_id'] > 0:
        rdv['seq_num'] = ripl_missing_num
        rdv['label'] = 'Total'
        output()

work['df2'] = (
    work['df']
        .transform(ripl_transform(
            by_cols=['customer_id', 'seq_num'],
            retain_cols=['counter'])
 )
```

# 常に再トレーニングは大変なものですが、支援するために我々がいます

マイグレーションの成功に向けたこの旅路は、混乱を引き起こし、フラストレーションとなるものかもしれません。しかし、あなたは一人ではなく、数千ものSASベースのプロフェッショナルがあなたと友に意義のある旅に参加しています。[WiseWithData](https://www.wisewithdata.com/)とDatabricksが、このプロセスより簡単なものにするために、ツール、リソースと共にあなたをサポートします。

SASプログラミング言語構成に対するPySparkプログラミングの基本的なハンズオンを受けるために、コース[Databricks for SAS Users](https://databricks.com/learn/training/home#)をトライしてみてください。そして、皆様SASチームがETLワークロードをDatabricksにオンボーディングし、ベストプラクティスを実現するために我々がどのように支援できるのかに関して、我々に[コンタクト](https://databricks.com/jp/company/contact)してください。

SAS®と他のSAS Institute Inc.の製品、サービス名は、アメリカと他の国においてSAS Institute Incの商標として登録されています。®はアメリカでの登録を意味します。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)