我正在学习图形(它们看起来非常有用),并且想知道我是否可以就构建图形的可能方法获得一些建议。
简单地说,让我们说我每天都会收到采购订单数据,有些日子与前一天相同,而其他日子则不同。例如,昨天我订购了铅笔和橡皮擦,我创建了两个节点来代表它们,然后今天我收到了橡皮擦和标记的订单,依此类推。在每一天之后,我的程序还会看到谁订购了什么,如果Bob昨天订购了一支铅笔,然后今天订购了一支橡皮,它就会产生一个有针对性的优势。我的逻辑是,我可以看到谁在每天购买了什么,我可以跟踪Bob的购买行为(也许可以用它来推断自己或其他用户的模式)。
我的问题是,我正在使用networkx(python)并为昨天创建节点'pencil',然后为day2创建另一个节点'pencil',我无法区分它们。
我想(并且已经)将它命名为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'}}
它明显覆盖了1/1/12的铅笔,只有1/2/12一支,不确定我是否可以分开一支。
答案 0 :(得分:2)
这主要取决于你的目标。您想要分析的是图表设计中的决定性因素。但是,查看您的结构,一般结构将是Customers
和Products
的节点,它们由Days
连接(我不知道这是否会对您有所帮助,但这个实际上是bipartite graph)。
所以你的结构会是这样的:
node(Person) --- edge(Day) ---> node(Product)
让我们说,鲍勃在2012年1月1日买了一支铅笔:
node(Bob) --- 1/1/12 ---> node(Pencil)
好的,现在Bob在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')]
到目前为止,还不错。你实际上可以查询诸如“爱丽丝是否在1/1/12购买铅笔?”之类的内容。
In : g.has_edge("Alice","Pencil","1/1/12")
Out: False
In : g.has_edge("Alice","Pencil","1/2/12")
Out: True
如果您想要特定日期的所有订单,情况可能会变糟。糟糕的是,我不是指代码方面,而是计算方面。代码方面它很简单:
In : [(from_node, to_node) for from_node, to_node, key in g.edges(keys=True) if key=="1/2/12"]
Out: [('Bob', 'Pencil'), ('Alice', 'Pencil')]
但是这会扫描网络中的所有边缘并过滤掉您想要的边缘。我不认为networkx
有更好的方法。
答案 1 :(得分:0)
图表不是最佳方法。像MySQL这样的关系型数据库是存储这些数据并执行诸如何时购买的数据的正确工具。
答案 2 :(得分:0)
试试这个:
为每个节点提供唯一的整数ID。然后,创建一个字典,节点,这样:
nodes ['pencil'] = [1,4,...]< - 其中所有这些都对应于具有铅笔属性的节点。 将'铅笔'替换为您感兴趣的其他任何属性。
只需确保在使用'pencil'添加节点时,即可更新字典:
节点[ '铅笔']。追加(new_node_id)。同样节点删除。