NetworkXを用いたDatabricksにおけるネットワーク分析

こちらのマニュアルです。

https://docs.databricks.com/ja/machine-learning/graph-analysis.html

以前、[GraphFrames](https://qiita.com/taka_yayoi/items/6d90f8cb8bd661e8e26b)を触ったことはありましたが、NetworkXは初です。使い分けは以下の通り。

>  1 つのコンピュート ノードで処理できる比較的小規模なネットワークの場合は、 [NetworkX](https://networkx.org/) を使用します。 分散処理が必要な大規模なネットワークの場合は、 [GraphFrames](https://docs.databricks.com/ja/integrations/graphframes/index.html) を使用します。 

サンプルノートブックをウォークスルーします。

# NetworkXを用いたグラフ分析

このノートブックでは、NetworkXを使用した基本的なグラフ分析について説明します。NetworkXは、複雑なネットワークの構造、動態、および機能を作成、操作、および研究するためのPythonパッケージです。このノートブックでは、[NetworkXのドキュメント](https://networkx.org/documentation/stable/index.html)からの例や、Databricksの組み込みデータセットを使用します。

NetworkXは、Databricks Runtime for Machine Learningにプリインストールされています。

## グラフ分析とは？
グラフは、異なるエンティティ間の関係を表現および分析するのに優れています。グラフを使用することで、輸送、物流、通信ネットワーク、製品推薦、ソーシャルネットワークなど、さまざまなビジネスにおける問題の理解と分析に役立ちます。

グラフでは、ノードまたは頂点が何らかの方法でリンクされたエンティティを表し、エッジがエンティティ間のリンクまたは関係を表します。このノートブックにはいくつかの例が含まれています。

## 要件
このノートブックには、Databricks Runtime for Machine Learningが必要です。

## 引用
* [NetworkX](https://networkx.org/documentation/stable/index.html). Aric A. Hagberg, Daniel A. Schult and Pieter J. Swart, “Exploring network structure, dynamics, and function using NetworkX”, in Proceedings of the 7th Python in Science Conference (SciPy2008), Gäel Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11–15, Aug 2008.

```py
# 必要なパッケージをインポート
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
```

## パート1. 基本的な例
このセクションでは、NetworkXに組み込まれているグラフを使用して基本的なグラフプロパティのいくつかの例を示します。最初の例は、シミュレートされたインターネットグラフです。ノードはホスト（コンピュータやその他のデバイス）を表し、エッジはホスト間のリンクを表します。

### ネットワークを作成する

```py
EX_1 = nx.random_internet_as_graph(50, seed=1)
```

### NetworkXとMatplotlibを使用してネットワークを描画する

```py
# 新しいAxesオブジェクトを作成
fig, ax = plt.subplots()

# Axesオブジェクトを使用してグラフを描画
nx.draw_networkx(EX_1)

# プロットを表示
plt.show()
```
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7da90031-c9c5-583e-d276-e4e128e36aa8.png)

### 基本的なネットワーク分析
無向ネットワークにおけるノードの次数は、そのノードに接続されているエッジの数です。次のコマンドは、ネットワーク内の各ノードの次数を表示します。

```py
sorted(EX_1.degree, key=lambda x: x[1], reverse=True)
```
```
[(7, 14),
 (8, 14),
 (6, 13),
 (2, 11),
 (3, 10),
 (9, 8),
 (5, 7),
 (11, 7),
 (1, 6),
 (4, 6),
 (0, 5),
 (10, 5),
 (12, 2),
 (13, 2),
 (14, 1),
 (15, 1),
 (16, 1),
 (17, 1),
 (18, 1),
 (19, 1),
 (20, 1),
 (21, 1),
 (22, 1),
 (23, 1),
 (24, 1),
 (25, 1),
 (26, 1),
 (27, 1),
 (28, 1),
 (29, 1),
 (30, 1),
 (31, 1),
 (32, 1),
 (33, 1),
 (34, 1),
 (35, 1),
 (36, 1),
 (37, 1),
 (38, 1),
 (39, 1),
 (40, 1),
 (41, 1),
 (42, 1),
 (43, 1),
 (44, 1),
 (45, 1),
 (46, 1),
 (47, 1),
 (48, 1),
 (49, 1)]
```

#### ノードの隣接ノード

`all_neighbors` コマンドは、指定されたノードに直接リンクされているすべてのノードを表示します。以下の例では、ノード6にリンクされているすべての隣接ノードが出力に表示されます。

```py
print([p for p in nx.all_neighbors(EX_1, 6)])
```
```
[3, 2, 22, 24, 25, 30, 39, 40, 49, 4, 5, 9, 8]
```

#### 半径、直径、離心率およびその他の測定値
以下のプロパティの詳細については、Databricksのドキュメント（[AWS](https://docs.databricks.com/ja/machine-learning/graph-analysis.html) | [Azure](https://learn.microsoft.com/ja-jp/azure/databricks/machine-learning/graph-analysis) | [GCP](https://docs.gcp.databricks.com/ja/machine-learning/graph-analysis.html)）を参照してください。

```py
print(f"diameter: {nx.diameter(EX_1)}")
print(f"density: {nx.density(EX_1)}")
```
```
diameter: 4
density: 0.05959183673469388
```

#### 最短経路
最短経路アルゴリズムは、2つのノード間の最短経路を見つけます。結果は経路上のノードを示します。

```py
nx.shortest_path(EX_1, 33, 47)
```
```
[33, 7, 2, 8, 47]
```

#### スモールワールドネットワーク
多くの現実世界のネットワークは「スモールワールド」ネットワークであり、密に接続されたサブネットワークと低い平均最短経路距離が特徴です。NetworkXの`omega`関数は、グラフがどれだけスモールワールドを表しているかを測定するものです。詳細については、[NetworkX omega ドキュメント](https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.smallworld.omega.html)を参照してください。

```py
# オメガはスモールワールドグラフに関連する指標です。オメガの値が0に近い場合、それはスモールワールドグラフを示します。

nx.omega(EX_1)
```
```
-0.0023529411764706687
```

#### 次数分布
ネットワークの次数分布は、各次数のノードの数を示します。次数分布はネットワークの重要な特徴であり、ネットワークがどのような性質を持つかを示します。

```py
degree_sequence = sorted((d for n, d in EX_1.degree()), reverse=True)

fig = plt.figure(figsize=(8, 8))
axgrid = plt.GridSpec(6, 4)

ax1 = fig.add_subplot(axgrid[3:, :2])
ax1.plot(degree_sequence, marker="o")
ax1.set_title("Degree rank plot")
ax1.set_ylabel("Degree")
ax1.set_xlabel("Rank")

ax2 = fig.add_subplot(axgrid[3:, 2:])
ax2.bar(*np.unique(degree_sequence, return_counts=True))
ax2.set_title("Degree histogram")
ax2.set_xlabel("Degree")
ax2.set_ylabel("# of nodes")

fig.tight_layout()
plt.show()
```
![download (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3a7c2073-65fa-9e81-7aaa-b4048efd0a2f.png)

## パート2. フライトデータの分析
このノートブックの残りの部分では、Databricksに組み込まれているデータセットを使用してフライトデータを分析します。

```py
# データセットをPandas DataFrameにロードしてデータを確認する

df = pd.read_csv("/databricks-datasets/asa/airlines/2007.csv")
df
```
![Screenshot 2024-12-20 at 20.54.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/60bc551b-4e13-c84e-db5b-1d840db68185.png)

### グラフの作成
このデータセットのようなフライトデータでは、方向が重要です。サンフランシスコからロサンゼルスへのフライトは、ロサンゼルスからサンフランシスコへのフライトと同等ではありません。このデータセットを表現するために、NetworkXでDiGraphと呼ばれる有向グラフを作成する必要があります。

`from_pandas_edgelist`メソッドを使用してNetworkXのDiGraphを作成します。詳細については、[NetworkXのドキュメント](https://networkx.org/documentation/stable/reference/generated/networkx.convert_matrix.from_pandas_edgelist.html)を参照してください。

```py
# データセットには各フライトに関する多くの情報が含まれています。グラフ分析を説明するために、このノートブックでは各フライトの出発地と目的地の空港のみに焦点を当てます。
df = df[["Origin", "Dest"]]

A = nx.from_pandas_edgelist(df, source='Origin', target='Dest', create_using=nx.DiGraph())
```

#### 次数中心性 
次数中心性は、あるノードが接続しているノードの数を測定する指標です。次のセルの結果は、アトランタ（ATL）、シカゴ・オヘア（ORD）、ダラス・フォートワース（DFW）などの忙しいハブ空港が最も高い次数中心性を持っていることを示しています。

```py
dict(sorted(nx.degree_centrality(A).items(), key=lambda item: item[1], reverse=True))
```
```
{'ATL': 1.197411003236246,
 'ORD': 0.9676375404530745,
 'DFW': 0.854368932038835,
 'MSP': 0.8381877022653722,
 'DEN': 0.7669902912621359,
 'CVG': 0.7508090614886732,
 'SLC': 0.7443365695792881,
 'IAH': 0.7443365695792881,
 'DTW': 0.7411003236245955,
 'LAS': 0.5922330097087379,
 'EWR': 0.5889967637540453,
 'LAX': 0.5792880258899676,
 'PHX': 0.56957928802589,
 'MCO': 0.5372168284789645,
 'MEM': 0.49838187702265374,
 'CLT': 0.46925566343042074,
 'JFK': 0.46601941747572817,
 'CLE': 0.4563106796116505,
 'SFO': 0.44012944983818775,
 'BWI': 0.4336569579288026,
 'IAD': 0.4336569579288026,
 'BOS': 0.41423948220064727,
 'LGA': 0.4077669902912622,
 'TPA': 0.4045307443365696,
 'SEA': 0.3786407766990291,
 'MDW': 0.3754045307443366,
 'PHL': 0.37216828478964403,
 'DCA': 0.3592233009708738,
 'AUS': 0.34304207119741104,
 'SAN': 0.33980582524271846,
 'FLL': 0.33333333333333337,
 'STL': 0.3300970873786408,
 'MCI': 0.31715210355987056,
 'MIA': 0.31067961165048547,
 'BNA': 0.3009708737864078,
 'RDU': 0.29449838187702265,
 'PDX': 0.27184466019417475,
 'MSY': 0.27184466019417475,
 'SMF': 0.2621359223300971,
 'PIT': 0.2621359223300971,
 'SAT': 0.255663430420712,
 'ABQ': 0.2524271844660194,
 'MKE': 0.2524271844660194,
 'IND': 0.2394822006472492,
 'ONT': 0.23624595469255666,
 'OAK': 0.23624595469255666,
 'JAX': 0.23624595469255666,
 'CMH': 0.22977346278317154,
 'HOU': 0.21035598705501618,
 'RSW': 0.21035598705501618,
 'BDL': 0.20711974110032363,
 'BHM': 0.19741100323624597,
 'SJC': 0.19093851132686085,
 'SDF': 0.1877022653721683,
 'TUS': 0.18446601941747573,
 'COS': 0.18446601941747573,
 'ANC': 0.18446601941747573,
 'OKC': 0.18122977346278318,
 'PBI': 0.1779935275080906,
 'SNA': 0.17475728155339806,
 'TUL': 0.17475728155339806,
 'HNL': 0.16181229773462785,
 'SJU': 0.15533980582524273,
 'MSN': 0.15210355987055016,
 'BUF': 0.1488673139158576,
 'OMA': 0.14563106796116507,
 'RNO': 0.14563106796116507,
 'BOI': 0.1423948220064725,
 'ORF': 0.1423948220064725,
 'PVD': 0.13592233009708737,
 'ELP': 0.13592233009708737,
 'GSO': 0.13592233009708737,
 'LIT': 0.13268608414239483,
 'RIC': 0.12944983818770228,
 'OGG': 0.1262135922330097,
 'GRR': 0.12297734627831716,
 'MHT': 0.1197411003236246,
 'ROC': 0.1197411003236246,
 'GEG': 0.11326860841423948,
 'ALB': 0.11003236245954694,
 'PSP': 0.11003236245954694,
 'TYS': 0.11003236245954694,
 'SAV': 0.10679611650485438,
 'XNA': 0.10679611650485438,
 'GJT': 0.10679611650485438,
 'DAL': 0.10355987055016182,
 'CHS': 0.10355987055016182,
 'DAY': 0.10032362459546926,
 'SYR': 0.10032362459546926,
 'DSM': 0.10032362459546926,
 'FAT': 0.10032362459546926,
 'LGB': 0.10032362459546926,
 'PWM': 0.0970873786407767,
 'SRQ': 0.09385113268608415,
 'GSP': 0.09061488673139159,
 'BUR': 0.08737864077669903,
 'JAN': 0.08737864077669903,
 'EGE': 0.08414239482200647,
 'SBA': 0.08414239482200647,
 'SGF': 0.08414239482200647,
 'PIH': 0.08414239482200647,
 'HPN': 0.08090614886731393,
 'CAK': 0.08090614886731393,
 'LEX': 0.07766990291262137,
 'HSV': 0.07766990291262137,
 'TWF': 0.07766990291262137,
 'CAE': 0.0744336569579288,
 'MYR': 0.0744336569579288,
 'MLI': 0.0744336569579288,
 'MDT': 0.07119741100323625,
 'KOA': 0.07119741100323625,
 'MRY': 0.07119741100323625,
 'ICT': 0.06796116504854369,
 'MTJ': 0.06796116504854369,
 'CID': 0.06796116504854369,
 'HDN': 0.06796116504854369,
 'STT': 0.06796116504854369,
 'BFL': 0.06472491909385114,
 'BTV': 0.06472491909385114,
 'FNT': 0.06472491909385114,
 'FSD': 0.06148867313915858,
 'ISP': 0.05825242718446602,
 'BZN': 0.05825242718446602,
 'PIA': 0.05825242718446602,
 'PNS': 0.05501618122977347,
 'BTR': 0.05501618122977347,
 'ABE': 0.05501618122977347,
 'JAC': 0.05501618122977347,
 'IDA': 0.05501618122977347,
 'MAF': 0.05177993527508091,
 'GPT': 0.05177993527508091,
 'EUG': 0.05177993527508091,
 'GRB': 0.05177993527508091,
 'MFR': 0.05177993527508091,
 'SWF': 0.05177993527508091,
 'LBB': 0.04854368932038835,
 'SHV': 0.04854368932038835,
 'BGR': 0.04854368932038835,
 'DAB': 0.045307443365695796,
 'VPS': 0.045307443365695796,
 'LIH': 0.045307443365695796,
 'AVP': 0.045307443365695796,
 'FCA': 0.045307443365695796,
 'LNK': 0.045307443365695796,
 'TVC': 0.045307443365695796,
 'JNU': 0.045307443365695796,
 'AMA': 0.042071197411003236,
 'CHA': 0.042071197411003236,
 'FWA': 0.042071197411003236,
 'SBN': 0.042071197411003236,
 'ATW': 0.042071197411003236,
 'MSO': 0.042071197411003236,
 'RFD': 0.042071197411003236,
 'AVL': 0.03883495145631068,
 'TLH': 0.03883495145631068,
 'CRW': 0.03883495145631068,
 'ASE': 0.03883495145631068,
 'RAP': 0.03883495145631068,
 'ROA': 0.03883495145631068,
 'LAN': 0.03883495145631068,
 'SBP': 0.03883495145631068,
 'BIL': 0.03883495145631068,
 'YUM': 0.03559870550161812,
 'AZO': 0.03559870550161812,
 'FAR': 0.03559870550161812,
 'RDM': 0.03559870550161812,
 'FAI': 0.03559870550161812,
 'CRP': 0.03236245954692557,
 'MOB': 0.03236245954692557,
 'PHF': 0.03236245954692557,
 'PSC': 0.03236245954692557,
 'EVV': 0.03236245954692557,
 'MGM': 0.02912621359223301,
 'MFE': 0.02912621359223301,
 'DRO': 0.02912621359223301,
 'ACY': 0.02912621359223301,
 'MLB': 0.02912621359223301,
 'CPR': 0.02912621359223301,
 'GTF': 0.02912621359223301,
 'TRI': 0.02912621359223301,
 'PSE': 0.02912621359223301,
 'MQT': 0.02912621359223301,
 'HRL': 0.025889967637540454,
 'LFT': 0.025889967637540454,
 'BMI': 0.025889967637540454,
 'HLN': 0.025889967637540454,
 'KTN': 0.025889967637540454,
 'ILM': 0.022653721682847898,
 'PFN': 0.022653721682847898,
 'SGU': 0.022653721682847898,
 'CEC': 0.022653721682847898,
 'MOD': 0.022653721682847898,
 'AGS': 0.022653721682847898,
 'BGM': 0.022653721682847898,
 'BQN': 0.022653721682847898,
 'AEX': 0.01941747572815534,
 'MLU': 0.01941747572815534,
 'GRK': 0.01941747572815534,
 'ERI': 0.01941747572815534,
 'CWA': 0.01941747572815534,
 'MBS': 0.01941747572815534,
 'TTN': 0.01941747572815534,
 'SCE': 0.01941747572815534,
 'ACV': 0.01941747572815534,
 'RDD': 0.01941747572815534,
 'SPI': 0.01941747572815534,
 'STX': 0.01941747572815534,
 'MCN': 0.01941747572815534,
 'FSM': 0.01941747572815534,
 'RST': 0.01941747572815534,
 'SIT': 0.01941747572815534,
 'CLD': 0.016181229773462785,
 'ITO': 0.016181229773462785,
 'LWS': 0.016181229773462785,
 'SMX': 0.016181229773462785,
 'BIS': 0.016181229773462785,
 'OGD': 0.016181229773462785,
 'SCC': 0.016181229773462785,
 'BRW': 0.016181229773462785,
 'AKN': 0.016181229773462785,
 'CYS': 0.016181229773462785,
 'LRD': 0.012944983818770227,
 'CLL': 0.012944983818770227,
 'COD': 0.012944983818770227,
 'GUC': 0.012944983818770227,
 'CHO': 0.012944983818770227,
 'HTS': 0.012944983818770227,
 'SUN': 0.012944983818770227,
 'EKO': 0.012944983818770227,
 'BLI': 0.012944983818770227,
 'IPL': 0.012944983818770227,
 'CDC': 0.012944983818770227,
 'PVU': 0.012944983818770227,
 'TOL': 0.012944983818770227,
 'CMI': 0.012944983818770227,
 'LSE': 0.012944983818770227,
 'DLH': 0.012944983818770227,
 'PLN': 0.012944983818770227,
 'OTZ': 0.012944983818770227,
 'OME': 0.012944983818770227,
 'WRG': 0.012944983818770227,
 'PSG': 0.012944983818770227,
 'YAK': 0.012944983818770227,
 'CDV': 0.012944983818770227,
 'ADK': 0.012944983818770227,
 'PMD': 0.012944983818770227,
 'ACK': 0.012944983818770227,
 'PIR': 0.012944983818770227,
 'CIC': 0.00970873786407767,
 'IYK': 0.00970873786407767,
 'OXR': 0.00970873786407767,
 'ABI': 0.00970873786407767,
 'SUX': 0.00970873786407767,
 'DLG': 0.00970873786407767,
 'EAU': 0.00970873786407767,
 'HHH': 0.00970873786407767,
 'SLE': 0.00970873786407767,
 'ROW': 0.00970873786407767,
 'LCH': 0.006472491909385114,
 'BPT': 0.006472491909385114,
 'BRO': 0.006472491909385114,
 'FLG': 0.006472491909385114,
 'TEX': 0.006472491909385114,
 'BTM': 0.006472491909385114,
 'EYW': 0.006472491909385114,
 'GTR': 0.006472491909385114,
 'BQK': 0.006472491909385114,
 'CSG': 0.006472491909385114,
 'DHN': 0.006472491909385114,
 'GNV': 0.006472491909385114,
 'LYH': 0.006472491909385114,
 'ABY': 0.006472491909385114,
 'MEI': 0.006472491909385114,
 'FAY': 0.006472491909385114,
 'APF': 0.006472491909385114,
 'ILG': 0.006472491909385114,
 'VLD': 0.006472491909385114,
 'ISO': 0.006472491909385114,
 'OAJ': 0.006472491909385114,
 'TUP': 0.006472491909385114,
 'FLO': 0.006472491909385114,
 'TYR': 0.006472491909385114,
 'SPS': 0.006472491909385114,
 'TXK': 0.006472491909385114,
 'LAW': 0.006472491909385114,
 'ACT': 0.006472491909385114,
 'GGG': 0.006472491909385114,
 'SJT': 0.006472491909385114,
 'DBQ': 0.006472491909385114,
 'GFK': 0.006472491909385114,
 'MOT': 0.006472491909385114,
 'ELM': 0.006472491909385114,
 'CMX': 0.006472491909385114,
 'RHI': 0.006472491909385114,
 'ALO': 0.006472491909385114,
 'BET': 0.006472491909385114,
 'ADQ': 0.006472491909385114,
 'MTH': 0.006472491909385114,
 'SOP': 0.006472491909385114,
 'LWB': 0.006472491909385114,
 'GLH': 0.006472491909385114,
 'MKC': 0.006472491909385114,
 'PUB': 0.006472491909385114,
 'EWN': 0.006472491909385114,
 'WYS': 0.006472491909385114,
 'YKM': 0.006472491909385114,
 'INL': 0.006472491909385114,
 'BJI': 0.006472491909385114,
 'GST': 0.006472491909385114,
 'BFF': 0.003236245954692557}
```

#### 入次数と出次数
有向グラフでは、入次数（ノードに向かうエッジの数）と出次数（ノードから出るエッジの数）を使用します。NetworkXは、各ノードの入次数と出次数を直接表示する関数を提供しています。

```py
dict(sorted(A.out_degree(), key=lambda item: item[1], reverse=True))
```
```
{'ATL': 186,
 'ORD': 153,
 'DFW': 132,
 'MSP': 130,
 'SLC': 122,
 'DEN': 122,
 'IAH': 117,
 'DTW': 115,
 'CVG': 115,
 'LAS': 92,
 'EWR': 92,
 'LAX': 91,
 'PHX': 88,
 'MCO': 82,
 'MEM': 79,
 'CLT': 73,
 'CLE': 71,
 'JFK': 70,
 'SFO': 70,
 'IAD': 69,
 'BWI': 68,
 'TPA': 62,
 'BOS': 62,
 'SEA': 59,
 'MDW': 58,
 'PHL': 58,
 'LGA': 58,
 'AUS': 57,
 'SAN': 53,
 'DCA': 53,
 'FLL': 52,
 'STL': 51,
 'MCI': 48,
 'MIA': 47,
 'BNA': 46,
 'PIT': 45,
 'RDU': 45,
 'MKE': 44,
 'PDX': 43,
 'SMF': 41,
 'MSY': 41,
 'SAT': 41,
 'ABQ': 39,
 'OAK': 38,
 'ONT': 37,
 'IND': 36,
 'JAX': 35,
 'CMH': 34,
 'BDL': 33,
 'HOU': 32,
 'RSW': 32,
 'SDF': 30,
 'SJC': 29,
 'BHM': 29,
 'TUS': 29,
 'ANC': 29,
 'OKC': 28,
 'TUL': 28,
 'SNA': 27,
 'PBI': 27,
 'HNL': 25,
 'OMA': 24,
 'SJU': 24,
 'BUF': 23,
 'BOI': 23,
 'GSO': 23,
 'COS': 23,
 'ELP': 22,
 'RNO': 22,
 'ORF': 22,
 'MSN': 22,
 'RIC': 22,
 'LIT': 21,
 'PVD': 21,
 'MHT': 19,
 'GEG': 19,
 'ROC': 19,
 'OGG': 19,
 'XNA': 18,
 'PSP': 18,
 'ALB': 17,
 'SAV': 17,
 'CHS': 17,
 'TYS': 17,
 'LGB': 17,
 'DAL': 16,
 'GRR': 16,
 'SYR': 16,
 'DSM': 16,
 'BUR': 15,
 'SRQ': 15,
 'DAY': 15,
 'FAT': 15,
 'SBA': 15,
 'GSP': 14,
 'PWM': 14,
 'SGF': 14,
 'JAN': 13,
 'MDT': 13,
 'LEX': 13,
 'CAK': 13,
 'EGE': 13,
 'HPN': 12,
 'HSV': 12,
 'FSD': 12,
 'CAE': 11,
 'MYR': 11,
 'HDN': 11,
 'KOA': 11,
 'MRY': 11,
 'MLI': 11,
 'BZN': 11,
 'ICT': 10,
 'BTV': 10,
 'MFR': 10,
 'FNT': 10,
 'ISP': 9,
 'BFL': 9,
 'PNS': 9,
 'ABE': 9,
 'MTJ': 9,
 'CID': 9,
 'JAC': 9,
 'AVP': 9,
 'MSO': 9,
 'STT': 9,
 'MAF': 8,
 'BTR': 8,
 'GPT': 8,
 'CRW': 8,
 'RAP': 8,
 'EUG': 8,
 'FCA': 8,
 'SWF': 8,
 'LBB': 7,
 'DAB': 7,
 'SHV': 7,
 'VPS': 7,
 'CHA': 7,
 'BGR': 7,
 'LIH': 7,
 'SBP': 7,
 'ACY': 7,
 'PSC': 7,
 'IDA': 7,
 'BIL': 7,
 'FAR': 7,
 'LNK': 7,
 'TVC': 7,
 'JNU': 7,
 'AMA': 6,
 'AVL': 6,
 'TLH': 6,
 'ASE': 6,
 'GRB': 6,
 'LAN': 6,
 'YUM': 6,
 'ATW': 6,
 'AZO': 6,
 'RDM': 6,
 'PIA': 6,
 'FAI': 6,
 'CRP': 5,
 'MOB': 5,
 'FWA': 5,
 'ROA': 5,
 'SBN': 5,
 'PHF': 5,
 'MLB': 5,
 'SGU': 5,
 'GTF': 5,
 'EVV': 5,
 'TRI': 5,
 'HRL': 4,
 'LFT': 4,
 'MGM': 4,
 'MFE': 4,
 'BMI': 4,
 'ILM': 4,
 'DRO': 4,
 'GJT': 4,
 'TTN': 4,
 'PFN': 4,
 'HLN': 4,
 'LWS': 4,
 'CEC': 4,
 'MOD': 4,
 'PSE': 4,
 'MQT': 4,
 'KTN': 4,
 'AEX': 3,
 'MLU': 3,
 'GRK': 3,
 'ERI': 3,
 'CLD': 3,
 'CWA': 3,
 'ITO': 3,
 'MBS': 3,
 'SCE': 3,
 'SUN': 3,
 'EKO': 3,
 'CPR': 3,
 'BLI': 3,
 'ACV': 3,
 'RDD': 3,
 'BIS': 3,
 'RFD': 3,
 'STX': 3,
 'AGS': 3,
 'BGM': 3,
 'BQN': 3,
 'FSM': 3,
 'RST': 3,
 'SIT': 3,
 'BRW': 3,
 'AKN': 3,
 'LRD': 2,
 'CLL': 2,
 'COD': 2,
 'GUC': 2,
 'CHO': 2,
 'HTS': 2,
 'TWF': 2,
 'CIC': 2,
 'IPL': 2,
 'IYK': 2,
 'OXR': 2,
 'SPI': 2,
 'TOL': 2,
 'CMI': 2,
 'LSE': 2,
 'DLH': 2,
 'PLN': 2,
 'OTZ': 2,
 'OME': 2,
 'SCC': 2,
 'WRG': 2,
 'PSG': 2,
 'YAK': 2,
 'CDV': 2,
 'ADK': 2,
 'PMD': 2,
 'ACK': 2,
 'SLE': 2,
 'PIR': 2,
 'LCH': 1,
 'BPT': 1,
 'BRO': 1,
 'FLG': 1,
 'TEX': 1,
 'PIH': 1,
 'BTM': 1,
 'SMX': 1,
 'EYW': 1,
 'GTR': 1,
 'BQK': 1,
 'CSG': 1,
 'DHN': 1,
 'GNV': 1,
 'MCN': 1,
 'LYH': 1,
 'ABY': 1,
 'MEI': 1,
 'FAY': 1,
 'APF': 1,
 'ILG': 1,
 'VLD': 1,
 'ISO': 1,
 'OAJ': 1,
 'TUP': 1,
 'FLO': 1,
 'TYR': 1,
 'ABI': 1,
 'SPS': 1,
 'TXK': 1,
 'LAW': 1,
 'ACT': 1,
 'GGG': 1,
 'SJT': 1,
 'DBQ': 1,
 'GFK': 1,
 'MOT': 1,
 'SUX': 1,
 'ELM': 1,
 'CMX': 1,
 'RHI': 1,
 'ALO': 1,
 'BET': 1,
 'ADQ': 1,
 'DLG': 1,
 'MTH': 1,
 'EAU': 1,
 'SOP': 1,
 'HHH': 1,
 'LWB': 1,
 'GLH': 1,
 'MKC': 1,
 'EWN': 1,
 'WYS': 1,
 'YKM': 1,
 'INL': 1,
 'BJI': 1,
 'GST': 1,
 'ROW': 1,
 'CDC': 0,
 'OGD': 0,
 'PVU': 0,
 'CYS': 0,
 'BFF': 0,
 'PUB': 0}
```

#### データの前処理
このセクションでは、ルートごとにフライトをグループ化し、例示目的のために小さなテーブルを作成するためのサブセットを選択します。

```py
# Pandas DataFrame 'pdf' を Spark DataFrame に変換
spark_df = spark.createDataFrame(df)

# Spark DataFrame をテーブルとして保存
# アクセスできる Unity Catalog の場所にテーブル名を変更
spark_df.write.mode("overwrite").saveAsTable("users.takaaki_yayoi.all_airports")
```

```sql
%sql
DROP TABLE IF EXISTS users.takaaki_yayoi.sw_group
```

```sql
%sql
CREATE TABLE users.takaaki_yayoi.sw_group AS (
SELECT Origin, Dest, COUNT(*) AS count
FROM users.takaaki_yayoi.all_airports
WHERE Origin IN ("LAX", "LAS", "SAN", "SFO", "PHX")
AND Dest IN ("LAX", "LAS", "SAN", "SFO", "PHX")
GROUP BY Origin, Dest
ORDER BY COUNT DESC) 
```

```sql
%sql
SELECT * FROM users.takaaki_yayoi.sw_group
```
![Screenshot 2024-12-20 at 20.56.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5fca5cd7-c9f4-32e0-059e-eb92911cfe0d.png)


前のセルの結果に記載されているように、セルの結果はPySpark DataFrame `_sqldf` に保存されています。次のセルではそのDataFrameを使用します。

```py
df = _sqldf.toPandas()

# df を作成するための代替コード
# df = spark.table("docs.flight_data.sw_group").toPandas()

SW = nx.from_pandas_edgelist(
    df,
    source='Origin',
    target='Dest',
    edge_attr='count',
    create_using=nx.DiGraph()
)

weights = list(nx.get_edge_attributes(SW, 'count').values())
weights = [w / 1000 for w in weights]
       
# 新しい Axes オブジェクトを作成
fig, ax = plt.subplots()

# Axes オブジェクトを使用してグラフを描画
nx.draw_networkx(SW, ax=ax, with_labels=True, node_size=800, node_color="yellow", width=weights)
# プロットを表示
plt.show()
```
![download (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c1fd3d1f-29a4-2eaf-2b3f-aeb877d659e8.png)


### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

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