NetworkXを使用したPythonでのディレクトリの視覚化

Habrセクションをスクロールすると、Python はNetworkXライブラリに関する興味深い記事に出会いました 。 美しいグラフに感銘を受け、私はpython-skillを増やしてnetworkxを掘り下げることにしました。

画像

プロローグ



最初の質問は、視覚化のためにデータを取得する場所です。 ランダムなものを生成することは面白くありません。それらはモジュールキットにも含まれていました。 その後、ファイルシステムディレクトリをツリー形式でリストしたDosユーティリティツリーを思い出しました。 Pythonで美しいアナログを作成し、matplotlibを使用してnetworkxですべてを描画することが決定されました。



第1幕



Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  1. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  2. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  3. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  4. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  5. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  6. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  7. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  8. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  9. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  10. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G



  11. Copy Source | Copy HTML def get_tree (tree=[u "E:\\" ,], G=nx.Graph(), itr= 0 , max_itr= 900 ): point = tree.pop( 0 ) itr = itr + 1 sub_tree = [ os .path.join(point, x) for x in os .listdir(point) if os .path.isdir( os .path.join(point, x)) and not is_hidden_dir( os .path.join(point, x))] if sub_tree: tree.extend(sub_tree) G.add_edges_from( map ( lambda b : (point, b), sub_tree)) if tree and itr <= max_itr: return get_tree (tree, G, itr) else : return G





ここで、結果のグラフから判断して、それほど多くの音楽がないことが明らかになります。

コード自体は難しくありません。 ツリーを解析するためのディレクトリのリストが終了するか、指定された反復回数に達するまで、関数は再帰的にそれ自体を呼び出します。 ディレクトリがディレクトリリストからプッシュされるたびに、最初の要素が標準のpython os.listdir()サブディレクトリによって検索されます。 その後、リストがマージされ、結果のリンクがグラフ構造に追加されます。 主なトリックはis_hidden_​​dir()関数です。 ファイルが非表示かどうかを確認します。 最初は、この些細な作業は言語自体の手段で解決できると思っていました。 しかし、これはUnixシステムでのみ簡単であり、私が書いているWindowsでは、このタスクはマゾヒズムの色合いを帯びています。



第2幕



Copy Source | Copy HTML



  1. def is_hidden_​​dir (d):
  2. インポート sys、サブプロセス
  3. sysの 場合 プラットフォーム .startswith( "win" ):
  4. p = サブプロセス .check_output([ "attrib" 、d])
  5. pで'H'の 場合 Trueを返します[: 12 ] else False
  6. その他
  7. os .path.basename(d)[ 0 ] == '。'の 場合 Trueを返します そうでなければ




まず、システムであるユーザーを確認します。 Windowsでない場合、ファイルの隠しプロパティの定義は一般的です-ディレクトリの最初の文字はドット「。」でなければなりません。

Windowsの場合、すべてが非定型です。 同様のことを行う方法を考えて、ファイルにはnixのポイントとして明示的なプロパティがないことに気付きました。 PythonでWinAPIに対処したいという希望はありませんでした。 私がした汚いハックを使用することは残っていました。



Googleでのクイック検索により、コンソールユーティリティユーティリティattribが見つかりました。 当初はos.system()を介して実行することしか計画されていませんでしたが、ドキュメントは私を思いとどまらせました。 さらに、ユーティリティの出力は私にとって重要であり、操作が成功したという事実ではありませんでした。 mansでは、必要な関数subprocess.check_output()が見つかりましたが、これは引数の結果を返します。 詳細な検証は簡単で、最初の12文字でフラグ「H」の出現を見つける必要があります。 しかし、ここでは、Windowsでリラックスできませんでした。 彼が名前にラテン文字のみを含むディレクトリを処理している間、すべては穏やかでしたが、彼がロシアの手紙に着いたとき、彼は完全に働くことを拒否しました。 エンコーディングが彼に合わなかったのは論理的です。 軽いハートのデコーダーを挿入しました

Copy Source | Copy HTML



  1. p = サブプロセス .check_output([ "attrib" 、d.encode( 'cp1251' )])


しかし、Pythonはそのようなアイデアの成功をすぐに確信させ、今回は英語名での作業を拒否しました。

その結果、妥協案が生まれました。

Copy Source | Copy HTML



  1. p = subprocess .check_output([ "attrib" 、d.encode( 'cp1251'if isinstance (d、unicode) else d])




第3幕。 ファイナル



networkxで生成されたグラフを描画するだけで、すべてが開始されました。 ここで深く掘り下げなければならなかったことを理解するために長い間推測する必要はありません。 レンダリング関数は非常にシンプルです:

Copy Source | Copy HTML



  1. networkx nx として インポート
  2. matplotlib.pyplot plt としてインポート
  3. def main ():
  4. G = get_tree()
  5. nx.draw(G、with_labels = False、node_color = "blue" 、alpha = 0. 6 、node_size = 50
  6. plt.savefig( "edge_colormap.png"
  7. plt.show()


nx.draw()のポインターパラメーターは、グラフ自体を除いてオプションです。 NetwokXは、 matplotlibpygraphvizの 2つの視覚データレンダリングライブラリをサポートしています。 最初に、pygraphvizを使用することにしました。 私はそれをオフサイトからダウンロードし、インストールし、pygraphvizラッパーのインストールを開始しましたが、pipは呪われ、pygraphvizはWindowsの処理を拒否したと言いました。 さて、私たちは代替手段があると思った。 Matplotlibは問題なく立ち上がりましたが、グラフでスクリプトを開始したとき、私はまだNumPyを使用していないことにthatり始めました。 NumPyをダウンロードしてインストールします。 彼は私に何も求めず、ただ働き始めた。



結果のコードは次のようになります。

Copy Source | Copy HTML



  1. #-*-エンコード:utf-8
  2. networkx nx として インポート
  3. matplotlib.pyplot plt としてインポート
  4. 輸入 OS
  5. def get_tree (tree = [u "E:\\ Music" 、]、G = nx.Graph()、itr = 0 、max_itr = 900 ):
  6. ポイント= tree.pop( 0
  7. itr = itr + 1
  8. sub_tree = [ os .path.join(point、x) in os .listdir(point) in os .path.isdir( os .path.join(point、x)) is_hidden_​​diros .path.join(ポイント、x))]
  9. sub_treeの場合
  10. tree.extend(sub_tree)
  11. G.add_edges_from( maplambda b:(point、b)、sub_tree))
  12. ツリー itr <= max_itrの場合:
  13. get_tree (tree、G、itr)を返します
  14. その他
  15. リターン G
  16. def is_hidden_​​dir (d):
  17. インポート sys、サブプロセス
  18. sysの 場合 プラットフォーム .startswith( "win" ):
  19. p = subprocess .check_output([ "attrib" 、d.encode( 'cp1251'if isinstance (d、unicode) else d])
  20. pで'H'の 場合 Trueを返します[: 12 ] else False
  21. その他
  22. os .path.basename(d)[ 0 ] == '。'の 場合 Trueを返します そうでなければ
  23. def main ():
  24. G = get_tree ()
  25. nx.draw(G、with_labels = False、node_color = "blue" 、alpha = 0. 6 、node_size = 50
  26. plt.savefig( "edge_colormap.png"
  27. plt.show()
  28. __name__ == "__main__"の場合
  29. メイン ()




カーテン



システム全体のスナップショットを取得することはできませんでした。 十分なメモリまたは手がありません。

最後にいくつかの写真:

<img title = "" border = "0" alt = "" src = "








All Articles