BigQueryで2拠点間の距離を算出する

BigQueryで2拠点間の距離を算出します

# ライブラリのインストール

!pip install --upgrade pandas-gbq 'google-cloud-bigquery[bqstorage,pandas]'

# テーブルの作成

# データフレームの作成

仮のデータを作成します。

import pandas as pd

# データフレームの作成
df = pd.DataFrame(data=[['仙台駅', 38.26063926000281, 140.8822763620918],
                        ['青葉城', 38.252377384994105, 140.85612549176253],
                        ['榴岡公園', 38.26066273495602, 140.89707530354525],
                        ['ラーメン二郎仙台店', 38.26181864469619, 140.8662996759938]],
                  columns=['name', 'lat', 'lon'])

display(df)

# BigQueryと接続

from google.cloud import bigquery

# keyとなるjsonファイルを読み込み
KEY_PATH = '****.json'

bq_client = bigquery.Client.from_service_account_json(KEY_PATH)

# データセットの生成¶

# データセットの生成
dataset_id = 'sample_data'
bq_client.create_dataset(dataset_id)

for ds in bq_client.list_datasets():
    print(ds.dataset_id)

# テーブルの作成

# データ型の確認
df_columns = df.dtypes
df_columns = pd.DataFrame(df_columns).reset_index()
df_columns = df_columns.rename(columns={'index': 'columns', 0: 'type'})
# スキーマ
schema = []
for i in range(len(df_columns)):
    column = df_columns['columns'][i]
    dtype = str(df_columns['type'][i]).replace('datetime64[ns]', 'DATETIME')\
                                      .replace('int64', 'INTEGER')\
                                      .replace('object', 'STRING')
    schema.append(bigquery.SchemaField(column, dtype, mode="NULLABLE"))
# table_idを生成(形式 : project_name.dataset_id.table_name)
dataset = bq_client.get_dataset(dataset_id)
table_id = '%s.%s.spot_table' % (dataset.project, dataset.dataset_id)

# テーブル生成
table = bigquery.Table(table_id, schema=schema)
bq_client.create_table(table)

# pandasからデータを投入

pandasのDataFrameからそのままデータを投入する

# Tableを取得
table = bigquery.Table(table_id, schema=schema)

# DataFrameを投入
bq_client.insert_rows_from_dataframe(table, df)

# テーブルの確認

import pandas as pd

query = f'''SELECT * 
            FROM {table_id}'''

# strベースのクエリと、project_idが必要
df_gbq = pd.read_gbq(query, table_id.split(".")[0])
display(df_gbq)
name lat lon
仙台駅 38.260639 140.882276
青葉城 38.252377 140.856125
榴岡公園 38.260663 140.897075
ラーメン二郎仙台店 38.261819 140.866300

# BigQueryで各拠点間の組み合わせを作成

「CROSS JOIN」より、BigQueryで各拠点間の組み合わせを作成します。

import pandas as pd

query = f'''
        WITH t1 AS (
            SELECT
            t0.name AS o_name, t0.lat AS o_lat, t0.lon AS o_lon
            FROM 
                {table_id} AS t0 
        ),
        t2 AS (
            SELECT
            t0.name AS d_name, t0.lat AS d_lat, t0.lon AS d_lon
            FROM 
                {table_id} AS t0 
        )
        SELECT
            *
        FROM 
            t1 
        CROSS JOIN t2'''

# strベースのクエリと、project_idが必要
df_gbq = pd.read_gbq(query, table_id.split(".")[0])
display(df_gbq)
o_name o_lat o_lon d_name d_lat d_lon
榴岡公園 38.260663 140.897075 榴岡公園 38.260663 140.897075
榴岡公園 38.260663 140.897075 仙台駅 38.260639 140.882276
榴岡公園 38.260663 140.897075 ラーメン二郎仙台店 38.261819 140.866300
榴岡公園 38.260663 140.897075 青葉城 38.252377 140.856125

# BigQueryで2拠点間距離を算出

「st_distance」より、BigQueryで2拠点間距離(m)を算出します。

import pandas as pd

query = f'''
        WITH t1 AS (
            SELECT
            t0.name AS o_name, t0.lat AS o_lat, t0.lon AS o_lon
            FROM 
                {table_id} AS t0 
        ),
        t2 AS (
            SELECT
            t0.name AS d_name, t0.lat AS d_lat, t0.lon AS d_lon
            FROM 
                {table_id} AS t0 
        )
        SELECT
            *, 
            st_distance(
                st_geogpoint(o_lon, o_lat),
                st_geogpoint(d_lon, d_lat)
            ) as distance
        FROM (
            SELECT
                *
            FROM 
                t1 
            CROSS JOIN t2)'''

# strベースのクエリと、project_idが必要
df_gbq = pd.read_gbq(query, table_id.split(".")[0])
display(df_gbq)
o_name o_lat o_lon d_name d_lat d_lon distance
ラーメン二郎仙台店 38.261819 140.866300 ラーメン二郎仙台店 38.261819 140.866300 0.000000
ラーメン二郎仙台店 38.261819 140.866300 青葉城 38.252377 140.856125 1375.247245
ラーメン二郎仙台店 38.261819 140.866300 仙台駅 38.260639 140.882276 1401.073901
ラーメン二郎仙台店 38.261819 140.866300 榴岡公園 38.260663 140.897075 2690.088942

# 参考サイト

BigQueryで2点間の距離を計算する (opens new window)

BigQuery クエリ構文 (opens new window)

Pythonでndjsonの読み込みを実施する

Pythonでndjsonの読み込みを実施する

Pythonでndjsonの読み込みを実施します.

Pandasで連続データの重複を削除する

Pandasで連続データの重複を削除する

Pandasで連続データの重複を削除します