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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

8089閲覧

各ノード間の相関を表すdataframeから無向グラフのネットワーク図を作成したい

James1201

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

1クリップ

投稿2018/06/05 14:32

0から4で示されるの5つのノードとそれらの相関を示す以下の行列(データフレーム)について、

イメージ説明

があり、

・相関の大きさ=エッジの太さ
・相関が0.10以下は表示しない
・エッジの向きは考慮しない

という条件を付与したネットワーク図を作成したいのですが、一通り調べても初心者の自分にはなかなか参考になりそうなものはありませんでした。

ライブラリはnetworkxを使っており、実装の時には次元数n=1000程度の行列を考えています。
また無向グラフの場合、片側三角行列に直した方が良いとの情報もありましたが、一応手は加えずにそのままの状態にしてあります。

どなたか詳しい方にご教授お願いしたいです。
どうかよろしくお願い致します。

以下に完成のイメージ図を載せておきます。図右側の凡例は無くても大丈夫です。
引用元:https://bdastyle.net/tools/scatterplot/undirected-graph.html

こちらが、例に挙げた行列のデータフレームになります。

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

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

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

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

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

guest

回答2

0

ベストアンサー

以前に類似したものを実装したことがあるので掲載します。

python

1# 相関マトリクス作成 2corr_matrix = df.corr() 3 4# networkxに引き渡すエッジリストを準備 5edge_lists = [] 6 7for i in corr_matrix.index.values : 8 for j in corr_matrix.index.values : 9 #描画したいものだけを抽出する 10 if (corr_matrix.loc[i,j] > 0.10) & (corr_matrix.loc[i,j] != 1) : 11 tmp = (i,j,corr_matrix.loc[i,j]*10) #(from,to,weight)のタプルを作成 12 edge_lists.append(tmp) 13 14import networkx as nx 15 16# 描画の準備 17G = nx.Graph() 18G.add_weighted_edges_from(edge_lists) 19 20plt.figure(figsize=(18,18)) #描画対象に合わせて設定する 21 22np.random.seed(seed=1234) #ノードポジションの再現性を確保するためseedを設定する 23pos = nx.spring_layout(G) #ノードのポジションの計算 24 25 26nx.draw_networkx(G,pos=pos,font_size=15,alpha=0.8)

無向グラフの場合、A→Bのエッジを設定したらB→Aの設定は不要なのですが、上記ではその考慮をしていません。よってcorr_matrixが大きいと処理に時間を要するので必要に応じて改良してください。
エッジリストは、(from,to)だけでもOKです。私の場合は相関係数によってノード間の距離を変えたかったのでweightを設定しました。なお、weightがない場合はadd_weighted_edges_from()が使えませんので、公式ドキュメントなどで確認して変更してください。

投稿2018/06/05 21:13

R.Shigemori

総合スコア3376

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

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

James1201

2018/06/06 05:21

ありがとうございます。 解決しました。NW関連はまだまだ疎いのでこれからの参考にさせていただきます。 また機会がありましたらよろしくお願い致します。
guest

0

とりあえず書いてみました。

個人的には、大規模なデータでループを回すのは極力避けたいため、三角行列化やFilter処理などは DataFrame上で行い、df.stack()df.melt() などを使ってDataFrameから直接エッジリストを生成するのが良いかと思います。

以下サンプルです。

このデータで0.10以下をフィルターすると・・・なのですが。

Python

1import pandas as pd 2import numpy as np 3import networkx as nx 4import matplotlib.pyplot as plt 5 6df = pd.DataFrame( 7 [[1. ,0.00165727,0.31542317,0.29266571,0.01082075], 8 [0.00165727,1. ,0.16202656,0.03057694,0.15787778], 9 [0.31542317,0.16202656,1. ,0.01456645,0.02475163], 10 [0.29266571,0.03057694,0.01456645,1 ,0.04057993], 11 [0.01082075,0.15787778,0.02475163,0.04057993,1. ]]) 12 13# エッジの名前を定義(適当) 14edge_name = ['A','B','C','D','E'] 15df.index = df.columns = edge_name 16 17# 相関係数DFより右上の三角行列およびに 0.1以下のデータをマスク 18tmp_df = df.mask(np.triu(np.ones(df.shape)).astype(bool) | (df < 0.1)) 19# エッジリストを生成 20edge_lists = tmp_df.stack().reset_index().apply(tuple, axis=1).values 21 22G = nx.Graph() 23G.add_weighted_edges_from(edge_lists) 24pos = nx.circular_layout(G) 25# weight に応じてラインの太さを調整(適当) 26line_width = [d['weight']*20 for u,v,d in G.edges(data=True)] 27nx.draw_networkx(G, pos=pos, node_size=800, node_color='gray', width=line_width) 28 29plt.show()

投稿2018/06/06 00:40

magichan

総合スコア15898

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

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

James1201

2018/06/06 05:20

回答ありがとうございます。 とても参考になりましたが、今回、実装先のデータの次元が4桁ほどあるので汎用できる方をBAに致しました。 また、機会がありましたらよろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問