2012-01-11 18 views
0

私はグラフについて学んでいます(彼らは非常に役に立つと思われます)、私はグラフを構成する可能性のある方法について助言を得ることができるのだろうかと思っていました。同じ名前のノードを区別するための正しいグラフデータ構造は何ですか?

簡単に言えば、私は毎日注文日のデータを取得し、数日前の日と同じ日に、また他の日には異なる日を指定します。たとえば、昨日私は鉛筆と消しゴムを注文しました。私はそれらを表すために2つのノードを作成し、今日は消しゴムとマーカーなどの注文を受け取ります。毎日の後、私のプログラムは誰が何を注文したかを見ています。そして、ボブが昨日鉛筆を注文してから今日消しゴムを注文すると、それは有向エッジを作り出します。私の論理は、誰が毎日何を買ったかを見ることができ、ボブの購入行動を追跡することができます(そして、それを使って自分や他のユーザーとパターンを推測することもできます)。

私はnetworkx(python)を使用していて、昨日のノード「鉛筆」を作成し、次にday2の別のノード「鉛筆」を作成しています。

私はday2-pencilという名前をつけて、グラフ全体をスキャンし、 'day2-'を取り除いて鉛筆の注文を追跡すると考えました。これは私には間違っているようだ(プロセッサ上では高価ではない)。私は何とか毎日その部分グラフとしてマークすることができれば、特定の日または数日を勉強したいときに、グラフ全体をスキャンする必要はないということになります。

私のテストデータが大きくなるにつれ、そのテストデータはますます混乱するため、ベストプラクティスは何か疑問に思っていますか?任意の生成提案は素晴らしいでしょう(networkxはかなり完全なように見えるので、おそらくそれをやる方法があります)。

ありがとうございます!

アップデート:まだ運が、これは多分役に立つ:

import networkx as nx 
G=nx.Graph() 
G.add_node('pencil', day='1/1/12', colour='blue') 
G.add_node('eraser', day='1/1/12', colour='rubberish colour. I know thats not a real colour') 
G.add_node('pencil', day='1/2/12', colour='blue') 

私は、次のコマンドG.nodeを入力し得る結果は次のとおりです。

{'pencil': {'colour': 'blue', 'day': '1/2/12'}, 'eraser': {'colour': 'rubberish colour. I know thats not a real colour', 'day': '1/1/12'}} 

ITSは、明らかに1月1日から鉛筆を上書き/ 12分の1と12分の12、分かりにくいかどうかわかりません。

+0

私は属性を検索できるかどうか確認するために(運がない)試しました。私はおそらく、day1、day2、等の属性を追加することを考えていたし、その属性を持つすべてのノードを検索します。存在するかもしれませんが、見つけられませんでした。 – Lostsoul

答えて

2

これは実際にあなたの目標にほとんど依存しています。分析したいのは、グラフデザインの決定的な要素です。しかし、あなたの構造を見て、一般的な構造はDaysによって接続されているCustomersProductsのためのノードになります(これはあなたがどんなに良くなるか分かりませんが、実際はbipartite graphです)。

だからあなたの構造はこのようなものになるだろう:

node(Person) --- edge(Day) ---> node(Product) 

さんが言ってみましょう、ボブは1/1/12に鉛筆を購入:

node(Bob) --- 1/1/12 ---> node(Pencil) 

[OK]を、今、ボブは別の鉛筆を行くと購入します1/2/12上:

  -- 1/1/12 -- 
     /   \ 
node(Bob)    > node(Pencil) 
     \   /
      -- 1/2/12 -- 

ように...

これは実際にnetworkxで可能です。ノード間に複数のエッジがあるため、エッジの方向に応じてMultiGraph Mor MultiDiGraphのいずれかを選択する必要があります。

In : g = networkx.MultiDiGraph() 

In : g.add_node("Bob") 
In : g.add_node("Alice") 

In : g.add_node("Pencil") 

In : g.add_edge("Bob","Pencil",key="1/1/12") 
In : g.add_edge("Bob","Pencil",key="1/2/12") 

In : g.add_edge("Alice","Pencil",key="1/3/12") 
In : g.add_edge("Alice","Pencil",key="1/2/12") 

In : g.edges(keys=True) 
Out: 
[('Bob', 'Pencil', '1/2/12'), 
('Bob', 'Pencil', '1/1/12'), 
('Alice', 'Pencil', '1/3/12'), 
('Alice', 'Pencil', '1/2/12')] 

これまでのところ、悪くない。実際には、「Aliceは1/1/12にPencilを購入しましたか?」などの質問を実際に行うことができます。

In : g.has_edge("Alice","Pencil","1/1/12") 
Out: False 

In : g.has_edge("Alice","Pencil","1/2/12") 
Out: True 

特定の日にすべての注文が必要な場合は、状況が悪くなる可能性があります。悪いことに、私はコードワイズを意味するのではなく、計算上のことを意味します。コードによるとかなり簡単です:

しかし、これはネットワークのすべてのエッジをスキャンし、必要なものをフィルタリングします。私はnetworkxがこれ以上良い方法はないと思います。

0

グラフはこれに最適な方法ではありません。 MySQLなどのリレーショナルデータベースは、このデータを格納し、誰がいつ買ったかなどのクエリを実行するための適切なツールです。

0

これを試してください:

各ノードに一意の整数IDを付けます。

ノード['pencil'] = [1,4、...] < - これらはすべて鉛筆属性のノードに対応しています。 あなたが興味を持っている他のどんな属性で「鉛筆」を交換してください

をちょうどあなたが「鉛筆」を持つノードを追加するとき、あなたは辞書更新することを確認します。。

ノード[「鉛筆」]を追加(new_node_id)。ノードの削除と同様に

関連する問題