質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2122閲覧

時系列データから回遊情報を集計しサンキーダイヤグラムを描画したい

amateur_PGM

総合スコア25

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2022/12/10 06:57

編集2022/12/10 07:37

前提

お客様の回遊情報を集計し、どこのお店からどこのお店へ移動する経路が多いのかを可視化したいです。

実現したいこと

pythonで回遊情報の集計をし、経路分析を実現したいです。

発生している問題・エラーメッセージ

現状、Excelにて頑張っています。
SUBPRODUCT関数でお客様ごとにお店の順番までは出せたんですが
各お店同士の経路関係を集計する方法がわからずスタックしました。。。

■下データ
下記のようなお客様別の時系列データが数万行あります。

CustomerIDTimestore
110A store
111B store
112C store
114A store
210D store
211A store
319C store
320A store
410C store

■欲しい結果
経路ごとにパターンを洗い出し、人数集計を出したいです。

spot1spot2spot3spot4value
A store---10
A storeB store--30
A storeB storeC store-50
A storeB storeC storeD store50

他のパターンも同様に集計したいです。

試したこと

ExcelのSubproduct関数を用いて
CustomerID別に各お店の順番を算出し下記のデータまでは作れています。

CustomerIDTimestoreorder
110A store1
111B store2
112C store3
114A store4
210D store1
211A store2
319C store1
320A store2
410C store1

サンキーダイヤグラムはおそら下記でも作れるかなと思っています。
各お店間の相互方向と人数の集計さえできれば描画出来そうと思います。

python

1import pandas as pd 2 3data = [ 4 ["A store", "B store", 8], 5 ["A store", "C store", 4], 6 ["A store", "D store", 2], 7 ["B store", "C store", 8], 8 ["B store", "D store", 4], 9 ["C store", "D store", 2], 10] 11 12df = pd.DataFrame(data).rename( 13 {0: "from", 1: "to", 2: "value"}, 14 axis="columns", 15) 16 17 18import holoviews as hv 19hv.extension('bokeh') 20from holoviews import opts, dim 21 22basic_sankey = hv.Sankey( 23 df, 24 kdims=["from", "to"], 25 vdims=["value"], 26 label="Basic Sankey Diagram", 27).opts( 28 edge_color=dim("from").str(), 29) 30 31# Display the diagram in Jupyter. 32hv.ipython.display(basic_sankey)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

元のデータから、2店間の経路毎に個数を集計します。
あとはそれをもとに描画できます。
なお、bokehでは循環する経路は描画できないようなのでplotlyを利用しています。

Python

1 2import pandas as pd 3from io import StringIO 4import plotly.graph_objects as go 5 6# テストデータ 7s = """ID,Time,store 81,10,A 91,11,B 101,12,C 111,14,A 122,10,D 132,11,A 143,19,C 153,20,A 164,10,C""" 17df = pd.read_csv(StringIO(s)) 18 19# 経路毎に個数を集計 20df = df.sort_values(['ID', 'Time']) 21df['to'] = df['store'].shift(-1)[df['ID'] == df['ID'].shift(-1)].dropna() 22df = df.rename(columns={'store':'from'}).drop(columns=['Time']) 23 24df = df.groupby(['from','to']).size().reset_index(name='value') 25print(df) 26""" 27 from to value 280 A B 1 291 B C 1 302 C A 2 313 D A 1 32""" 33 34src, tgt, val = df['from'].values, df['to'].values, df['value'].values 35 36# 店名→番号の辞書 37lbl = {e:i for i,e in enumerate(sorted(set(src) | set(tgt)))} 38 39# 店名→番号に変換 40src = [lbl[e] for e in src] 41tgt = [lbl[e] for e in tgt] 42lbl = list(lbl.keys()) # 店名=ノード名 43 44# 描画 45fig = go.Figure([go.Sankey( 46 node = dict( pad = 15, thickness = 20, 47 line = dict(color = "black", width = 0.5), 48 label = lbl, color = "blue" ), 49 link = dict( source = src, target = tgt, value = val))]) 50fig.show()

イメージ説明

投稿2022/12/12 01:48

can110

総合スコア38352

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問