import csv, os
import numpy as np
import pandas as pd
# print pd.__version__
from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')
%matplotlib inline
data import
cb_data = pd.read_csv('data/b_styles_expanded.csv')
print cb_data.dtypes
cb_data.tail()
Unnamed: 0 int64
Unnamed: 0.1 int64
beer_style object
cheese object
Finish Length object
Phenols object
Alcohol object
Hops object
dessert object
Malt object
other_styles object
glass object
descrip_long object
Hop object
Body object
dish object
Carbonation (Visual) object
category object
Esters object
Attenuation object
temp object
Yeast object
Color object
srm object
Water object
abv object
Carbonation object
Clarity object
ibu object
Fermentation By-Products object
...
fruity float64
hoppy float64
malty float64
nutty float64
sour float64
spicy float64
abv_max float64
abv_min float64
ibu_max float64
ibu_min float64
srm_max float64
srm_min float64
temp_max float64
temp_min float64
temp_avg float64
temp_range float64
srm_avg float64
srm_range float64
abv_avg float64
abv_range float64
ibu_avg float64
ibu_range float64
Flute float64
Goblet float64
Nonic Pint float64
Snifter float64
Thistle float64
Tulip float64
Varies float64
Vase float64
dtype: object
Unnamed: 0 | Unnamed: 0.1 | beer_style | cheese | Finish Length | Phenols | Alcohol | Hops | dessert | Malt | ... | ibu_avg | ibu_range | Flute | Goblet | Nonic Pint | Snifter | Thistle | Tulip | Varies | Vase | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
72 | 72 | 72 | Session Beer | Varies | Varies | Can be present. | Not Detectable to Mild | Varies | Varies | Varies | ... | 20.0 | 20.0 | NaN | NaN | NaN | NaN | NaN | NaN | 1.0 | NaN |
73 | 73 | 73 | Smoke Beer | Parmesan | Varies | Can be present. | Varies | Varies | Gingerbread Cookies | Varies | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.0 |
74 | 74 | 74 | Smoke Porter | Red Dragon Cheddar | Medium to Long | Not common to style | Varies | Kent Goldings, Willamette | S'mores | Crystal, Chocolate, Black Patent | ... | 30.0 | 20.0 | NaN | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN |
75 | 75 | 75 | Specialty Beer | Varies | Varies | Can be present. | Varies | Varies | Varies | Varies | ... | 50.5 | 99.0 | NaN | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN |
76 | 76 | 76 | Vienna-Style Lager | Mild Cheeses | Short to Medium | Not common to style. | Mild | German Noble | Almond Biscotti | Vienna | ... | 25.0 | 6.0 | 1.0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 rows × 66 columns
# cb_data.to_csv('data/cb_data.csv', sep=';')
style_category = cb_data[['beer_style', 'category', 'other_styles']]
style_category.tail()
beer_style | category | other_styles | |
---|---|---|---|
72 | Session Beer | Specialty Beers | [English-Style Bitter, Irish-Style Dry Stout, ... |
73 | Smoke Beer | Specialty Beers | [English-Style Old Ale, American Brett, Herb a... |
74 | Smoke Porter | Porters | [English-Style Old Ale, American Brett, Herb a... |
75 | Specialty Beer | Specialty Beers | [Belgian-Style Fruit Lambic, Herb and Spice Be... |
76 | Vienna-Style Lager | Dark Lagers | [English-Style Bitter, German-Style Bock, Belg... |
style_category.other_styles[0][1:-1].split(',')
['English-Style Pale Ale/ESB', ' English-Style Mild', ' American Amber Lager']
# style_category.other_styles.str.slice(1,-1)
style_cat_dict = cb_data[['beer_style', 'category', 'other_styles']].to_dict('records')
print style_cat_dict[:3]
print ''
for style in style_cat_dict:
style['other_styles'] = style['other_styles'][1:-1].split(', ')
if style['other_styles'] == ['']:
style['other_styles'] = []
print style_cat_dict[:3]
print ''
print style_cat_dict[61]['other_styles']
[{'category': 'Pale Ales', 'beer_style': 'American Amber Ale', 'other_styles': '[English-Style Pale Ale/ESB, English-Style Mild, American Amber Lager]'}, {'category': 'Dark Lagers', 'beer_style': 'American Amber Lager', 'other_styles': '[German-Style Marzen/Oktoberfest, Vienna-Style Lager, English-Style Mild]'}, {'category': 'Strong Ales', 'beer_style': 'American Barley Wine', 'other_styles': '[Imperial India Pale Ale, German-Style Doppelbock, Scotch Ale/Wee Heavy]'}]
[{'category': 'Pale Ales', 'beer_style': 'American Amber Ale', 'other_styles': ['English-Style Pale Ale/ESB', 'English-Style Mild', 'American Amber Lager']}, {'category': 'Dark Lagers', 'beer_style': 'American Amber Lager', 'other_styles': ['German-Style Marzen/Oktoberfest', 'Vienna-Style Lager', 'English-Style Mild']}, {'category': 'Strong Ales', 'beer_style': 'American Barley Wine', 'other_styles': ['Imperial India Pale Ale', 'German-Style Doppelbock', 'Scotch Ale/Wee Heavy']}]
[]
beer_list = cb_data.beer_style.tolist()
beer_list[-5:]
['Session Beer',
'Smoke Beer',
'Smoke Porter',
'Specialty Beer',
'Vienna-Style Lager']
# possible links across all styles
77*76/2
2926
cb_DiLinks = []
for style in style_cat_dict:
if len(style['other_styles']) > 0:
for other in style['other_styles']:
cb_DiLinks.append((style['beer_style'], other))
print len(cb_DiLinks)
cb_DiLinks[:10]
187
[('American Amber Ale', 'English-Style Pale Ale/ESB'),
('American Amber Ale', 'English-Style Mild'),
('American Amber Ale', 'American Amber Lager'),
('American Amber Lager', 'German-Style Marzen/Oktoberfest'),
('American Amber Lager', 'Vienna-Style Lager'),
('American Amber Lager', 'English-Style Mild'),
('American Barley Wine', 'Imperial India Pale Ale'),
('American Barley Wine', 'German-Style Doppelbock'),
('American Barley Wine', 'Scotch Ale/Wee Heavy'),
('American Black Ale', 'Robust Porter')]
the bright idea
- identify duplicate/parallel/two way edges
- remove one “copy” at random
- run
nx.dag...
- iterate k times
- track, count and hist
source: https://networkx.github.io/documentation/development/reference/classes.digraph.html#information-about-graph-structure
DiGraph.nodes_with_selfloops()
Return a list of nodes with self loops.
DiGraph.selfloop_edges([data])
Return a list of selfloop edges.
DiGraph.number_of_selfloops()
Return the number of selfloop edges.
import networkx as nx
# colors from our friends at http://colorbrewer2.org
COLORS = ['#8dd3c7','#ffffb3','#bebada','#fb8072','#80b1d3','#fdb462',
'#b3de69','#fccde5','#d9d9d9','#bc80bd','#ccebc5','#ffed6f']
G_toy = nx.DiGraph()
G_toy.add_nodes_from(['Alice', 'Bob', 'Chuck', 'Dick', 'Edgar', 'Fred'])
G_toy.nodes()
['Dick', 'Alice', 'Edgar', 'Fred', 'Chuck', 'Bob']
G_toy.add_edges_from([('Alice', 'Bob'), ('Alice', 'Chuck'), ('Bob', 'Alice'), ('Bob', 'Chuck'),
('Chuck', 'Dick'), ('Alice', 'Dick'), ('Bob', 'Edgar'), ('Edgar', 'Bob'),
('Dick', 'Fred'), ('Fred' , 'Dick')
])
G_toy.edges()
[('Dick', 'Fred'),
('Alice', 'Bob'),
('Alice', 'Dick'),
('Alice', 'Chuck'),
('Edgar', 'Bob'),
('Fred', 'Dick'),
('Chuck', 'Dick'),
('Bob', 'Alice'),
('Bob', 'Edgar'),
('Bob', 'Chuck')]
nx.draw_circular(G_toy,
node_color=COLORS[0],
node_size=2000,
with_labels=True)
plt.axis('equal')
(-1.5, 1.5, -1.5, 1.5)
toy set longest with cycle (above)
# from collections import Counter
# edge_count = Counter()
# for e in G_toy.edges_iter():
# a,b = sorted(e)
# edge_count[('_').join([a,b])] += 1
# edge_count
parallel edge identification
from collections import Counter
def pll_recreate(edge):
a,b = edge.split('_')
return (a,b), (b,a)
def pll_edges(G):
edge_count = Counter()
for e in G.edges_iter():
a,b = sorted(e)
edge_count[('_').join([a,b])] += 1
edge_dupes = [k for k in edge_count if edge_count[k] > 1]
return [pll_recreate(e) for e in edge_dupes]
print pll_edges(G_toy)
[(('Dick', 'Fred'), ('Fred', 'Dick')), (('Bob', 'Edgar'), ('Edgar', 'Bob')), (('Alice', 'Bob'), ('Bob', 'Alice'))]
import time
# t1 = time.time()
# for i in range(10000):
# H = G_toy.copy()
# H.remove_edges_from([e[np.random.random() < .5] for e in x])
# time.time() - t1
# 10x faster to remove/add edges than to copy graph
t1 = time.time()
long_paths = Counter()
x = pll_edges(G_toy)
for i in range(10000):
pll_hold = [e[np.random.random() < .5] for e in x]
G_toy.remove_edges_from(pll_hold)
long_paths[nx.dag_longest_path_length(G_toy)] += 1
G_toy.add_edges_from(pll_hold)
print long_paths
time.time() - t1
Counter({4: 4968, 3: 3753, 5: 1279})
0.3600001335144043
plt.bar(long_paths.keys(), long_paths.values(), 0.25, color='g', align='center')
<Container object of 3 artists>
def lng_path(G, sim=1000):
long_paths = Counter()
parallel_e = pll_edges(G)
for i in range(sim):
pll_hold = [e[np.random.random() < .5] for e in parallel_e]
G.remove_edges_from(pll_hold)
long_paths[nx.dag_longest_path_length(G)] += 1
G.add_edges_from(pll_hold)
return long_paths
print lng_path(G_toy, 10000)
Counter({4: 4979, 3: 3798, 5: 1223})
test (cross your fingers!)
Directed Graph
G = nx.DiGraph()
G.add_nodes_from(beer_list)
print len(G.nodes())
G.nodes()[:3]
77
['German-Style Bock', 'German-Style Dunkelweizen', 'Belgian-Style Tripel']
G.add_edges_from(cb_DiLinks)
print len(G.edges())
G.edges()[:3]
186
[('German-Style Bock', 'Belgian-Style Dubbel'),
('German-Style Bock', 'American Amber Lager'),
('German-Style Dunkelweizen', 'English-Style Brown Ale')]
# why is the edge count lower than list len?
# must be a dupe
# https://stackoverflow.com/questions/9835762/find-and-list-duplicates-in-a-list
set([x for x in cb_DiLinks if cb_DiLinks.count(x) > 1])
{('Rye Beer', 'Herb and Spice Beer')}
print pll_edges(G)
[(('Belgian-Style Dubbel', 'German-Style Dunkel'), ('German-Style Dunkel', 'Belgian-Style Dubbel')), (('Chocolate Beer', 'Coffee Beer'), ('Coffee Beer', 'Chocolate Beer')), (('American Black Ale', 'American India Pale Ale/IPA'), ('American India Pale Ale/IPA', 'American Black Ale')), (('Belgian-Style Lambic/Gueuze', 'Fruit and Field Beer'), ('Fruit and Field Beer', 'Belgian-Style Lambic/Gueuze')), (('German-Style Doppelbock', 'Scotch Ale/Wee Heavy'), ('Scotch Ale/Wee Heavy', 'German-Style Doppelbock')), (('Herb and Spice Beer', 'Honey Beer'), ('Honey Beer', 'Herb and Spice Beer')), (('Belgian-Style Wit', 'German-Style Hefeweizen'), ('German-Style Hefeweizen', 'Belgian-Style Wit')), (('English-Style Old Ale', 'German-Style Doppelbock'), ('German-Style Doppelbock', 'English-Style Old Ale')), (('German-Style Schwarzbier', 'Irish-Style Dry Stout'), ('Irish-Style Dry Stout', 'German-Style Schwarzbier')), (('American Amber Lager', 'English-Style Mild'), ('English-Style Mild', 'American Amber Lager')), (('Belgian-Style Dubbel', 'English-Style Brown Porter'), ('English-Style Brown Porter', 'Belgian-Style Dubbel')), (('English-Style Brown Porter', 'German-Style Dunkel'), ('German-Style Dunkel', 'English-Style Brown Porter')), (('American Black Ale', 'Robust Porter'), ('Robust Porter', 'American Black Ale')), (('American Amber Ale', 'English-Style Pale Ale/ESB'), ('English-Style Pale Ale/ESB', 'American Amber Ale')), (('American Amber Lager', 'German-Style Marzen/Oktoberfest'), ('German-Style Marzen/Oktoberfest', 'American Amber Lager')), (('American Imperial Porter', 'Chocolate Beer'), ('Chocolate Beer', 'American Imperial Porter')), (('English-Style Bitter', 'Session Beer'), ('Session Beer', 'English-Style Bitter')), (('American Sour', 'Barrel-Aged Beer'), ('Barrel-Aged Beer', 'American Sour'))]
edge_hold = [e[np.random.random() < .5] for e in pll_edges(G)]
edge_hold
[('Belgian-Style Dubbel', 'German-Style Dunkel'),
('Chocolate Beer', 'Coffee Beer'),
('American Black Ale', 'American India Pale Ale/IPA'),
('Fruit and Field Beer', 'Belgian-Style Lambic/Gueuze'),
('Scotch Ale/Wee Heavy', 'German-Style Doppelbock'),
('Honey Beer', 'Herb and Spice Beer'),
('German-Style Hefeweizen', 'Belgian-Style Wit'),
('German-Style Doppelbock', 'English-Style Old Ale'),
('Irish-Style Dry Stout', 'German-Style Schwarzbier'),
('American Amber Lager', 'English-Style Mild'),
('Belgian-Style Dubbel', 'English-Style Brown Porter'),
('German-Style Dunkel', 'English-Style Brown Porter'),
('Robust Porter', 'American Black Ale'),
('American Amber Ale', 'English-Style Pale Ale/ESB'),
('German-Style Marzen/Oktoberfest', 'American Amber Lager'),
('Chocolate Beer', 'American Imperial Porter'),
('English-Style Bitter', 'Session Beer'),
('American Sour', 'Barrel-Aged Beer')]
len(edge_hold)
18
print len(G.edges())
G.remove_edges_from(edge_hold)
print len(G.edges())
G.add_edges_from(edge_hold)
print len(G.edges())
186
168
186
nx.dag_longest_path_length(G)
---------------------------------------------------------------------------
NetworkXUnfeasible Traceback (most recent call last)
<ipython-input-29-f12868cc9541> in <module>()
----> 1 nx.dag_longest_path_length(G)
<decorator-gen-224> in dag_longest_path_length(G)
C:\Users\rstancut\AppData\Local\Continuum\Anaconda2\lib\site-packages\networkx\utils\decorators.pyc in _not_implemented_for(f, *args, **kwargs)
66 ' '.join(graph_types))
67 else:
---> 68 return f(*args,**kwargs)
69 return _not_implemented_for
70
C:\Users\rstancut\AppData\Local\Continuum\Anaconda2\lib\site-packages\networkx\algorithms\dag.pyc in dag_longest_path_length(G)
454 dag_longest_path
455 """
--> 456 path_length = len(nx.dag_longest_path(G)) - 1
457 return path_length
<decorator-gen-222> in dag_longest_path(G)
C:\Users\rstancut\AppData\Local\Continuum\Anaconda2\lib\site-packages\networkx\utils\decorators.pyc in _not_implemented_for(f, *args, **kwargs)
66 ' '.join(graph_types))
67 else:
---> 68 return f(*args,**kwargs)
69 return _not_implemented_for
70
C:\Users\rstancut\AppData\Local\Continuum\Anaconda2\lib\site-packages\networkx\algorithms\dag.pyc in dag_longest_path(G)
416 """
417 dist = {} # stores [node, distance] pair
--> 418 for node in nx.topological_sort(G):
419 # pairs of dist,node for all incoming edges
420 pairs = [(dist[v][0] + 1, v) for v in G.pred[node]]
C:\Users\rstancut\AppData\Local\Continuum\Anaconda2\lib\site-packages\networkx\algorithms\dag.pyc in topological_sort(G, nbunch, reverse)
155 if n not in explored:
156 if n in seen: # CYCLE !!
--> 157 raise nx.NetworkXUnfeasible("Graph contains a cycle.")
158 new_nodes.append(n)
159 if new_nodes: # Add new_nodes to fringe
NetworkXUnfeasible: Graph contains a cycle.
loop identification
G_toy2 = nx.DiGraph()
G_toy2.add_nodes_from(['Alice', 'Bob', 'Chuck', 'Dick'])
# G_toy2.nodes()
G_toy2.add_edges_from([('Alice', 'Bob'), ('Bob', 'Chuck'), ('Chuck', 'Dick'), ('Dick', 'Alice')])
G_toy2.edges()
[('Bob', 'Chuck'), ('Dick', 'Alice'), ('Alice', 'Bob'), ('Chuck', 'Dick')]
nx.draw_circular(G_toy2,
node_color=COLORS[0],
node_size=2000,
with_labels=True)
plt.axis('equal')
(-1.5, 1.5, -1.5, 1.5)
next bright idea
- after removing parallel edges (at random)
- shuffle nodes, find loop edges, and remove
-
run
nx.dag...
- add back all removed edges, parallel & loop
- iterate process
# Think Complexity2, ch2
def reachable_nodes(G, start):
seen = set()
stack = [start]
while stack:
node = stack.pop()
if node not in seen:
seen.add(node)
stack.extend(G.neighbors(node))
return seen
reachable_nodes(G_toy2, 'Alice')
{'Alice', 'Bob', 'Chuck', 'Dick'}
def loop_edge(G, start):
seen = set()
stack = [start]
loops = []
while stack:
node = stack.pop()
if node not in seen:
seen.add(node)
stack.extend(G.neighbors(node))
for n in G[node]:
if n in seen:
loops.append((node, n))
return loops
loop_edge(G_toy2, 'Dick')
[('Chuck', 'Dick')]
for n in G_toy2.nodes():
print n, loop_edge(G_toy2,n)
Bob [('Alice', 'Bob')]
Dick [('Chuck', 'Dick')]
Alice [('Dick', 'Alice')]
Chuck [('Bob', 'Chuck')]
# G_toy2 = nx.DiGraph()
# G_toy2.add_nodes_from(['Alice', 'Bob', 'Chuck', 'Dick'])
# # G_toy2.nodes()
# G_toy2.add_edges_from([('Alice', 'Bob'), ('Bob', 'Chuck'), ('Chuck', 'Dick'), ('Dick', 'Alice')])
# G_toy2.edges()
long_paths = Counter()
loop_hold = []
for n in np.random.permutation(G_toy2.nodes()):
print n
print loop_edge(G_toy2,n)
loop_hold.extend(loop_edge(G_toy2,n))
G_toy2.remove_edges_from(loop_hold)
long_paths[nx.dag_longest_path_length(G_toy2)] += 1
# G_toy2.add_edges_from(loop_hold)
print loop_hold
print long_paths
print len(G_toy2.edges())
G_toy2.add_edges_from(loop_hold)
print len(G_toy2.edges())
Chuck
[('Bob', 'Chuck')]
Bob
[]
Dick
[]
Alice
[]
[('Bob', 'Chuck')]
Counter({3: 4})
3
4
def lng_path_cnt(G, sim=1000):
long_paths = Counter()
parallel_e = pll_edges(G)
print len(G), len(G.edges())
for i in range(sim):
pll_hold = [e[np.random.random() < .5] for e in parallel_e]
G.remove_edges_from(pll_hold)
loop_hold = []
for n in np.random.permutation(G.nodes()):
loop_hold.extend(loop_edge(G,n))
G.remove_edges_from(loop_hold)
long_paths[nx.dag_longest_path_length(G)] += 1
G.add_edges_from(pll_hold)
G.add_edges_from(loop_hold)
print len(G), len(G.edges())
return long_paths
long_paths2 = lng_path_cnt(G)
print long_paths2
print np.max([k for k in long_paths2])
77 186
77 186
Counter({9: 165, 10: 150, 12: 131, 8: 124, 11: 115, 13: 86, 7: 44, 15: 43, 14: 38, 16: 28, 19: 20, 18: 19, 17: 15, 20: 11, 21: 5, 6: 4, 22: 2})
22
# now run it 10k times
long_paths2 = lng_path_cnt(G, 20000)
plt.bar(long_paths2.keys(), long_paths2.values(), 0.25, color='g', align='center')
lp = np.max([k for k in long_paths2])
plt.vlines(lp,0, 2000, color='r', linestyles=':')
plt.text(lp-1, 1000, "long path count: %d" % lp, rotation=90, verticalalignment='center')
77 186
77 186
<matplotlib.text.Text at 0xbbda2b0>
def lng_path_list(G, sim=1000):
long_paths = []
path_count = 0
parallel_e = pll_edges(G)
print len(G), len(G.edges())
for i in range(sim):
pll_hold = [e[np.random.random() < .5] for e in parallel_e]
G.remove_edges_from(pll_hold)
loop_hold = []
for n in np.random.permutation(G.nodes()):
loop_hold.extend(loop_edge(G,n))
G.remove_edges_from(loop_hold)
temp_path = nx.dag_longest_path(G)
if len((nx.dag_longest_path(G))) >= path_count:
long_paths.append(temp_path)
path_count = len(temp_path)
# long_paths[nx.dag_longest_path_length(G)] += 1
G.add_edges_from(pll_hold)
G.add_edges_from(loop_hold)
print len(G), len(G.edges())
return long_paths
lng_path_list(G,50)[-1]
77 186
77 186
['European-Style Export',
'Belgian-Style Saison',
'American Pale Ale',
'Belgian-Style Pale Ale',
'American Amber Ale',
'American Amber Lager',
'Vienna-Style Lager',
'English-Style Bitter',
'Scottish-Style Ale',
'Belgian-Style Dubbel',
'English-Style Brown Porter',
'American Brown Ale',
'Fruit and Field Beer',
'American Sour',
'Belgian-Style Wit',
'Bohemian-Style Pilsener',
'American Wheat',
'Belgian-Style Tripel',
'German-Style Maibock',
'Belgian-Style Golden Strong Ale']
lng_path_names = lng_path_list(G,10000)[-1]
print len(lng_path_names)
lng_path_names
77 186
77 186
26
['European-Style Export',
'Belgian-Style Saison',
'Session Beer',
'English-Style Bitter',
'Belgian-Style Pale Ale',
'American Amber Ale',
'American Amber Lager',
'Vienna-Style Lager',
'Belgian-Style Dubbel',
'English-Style Brown Porter',
'American Brown Ale',
'Scottish-Style Ale',
'Barrel-Aged Beer',
'American Brett',
'German-Style Pilsener',
'Belgian-Style Tripel',
'German-Style Maibock',
'Belgian-Style Golden Strong Ale',
'American Wheat',
'Fruit and Field Beer',
'American Sour',
'Belgian-Style Wit',
'Bohemian-Style Pilsener',
'German-Style Kolsch',
'English-Style Pale Ale/ESB',
'German-Style Bock']
add surrounding beers for context
G2 = nx.DiGraph()
for style in lng_path_names:
G2.add_node(style)
G2.add_nodes_from(G.neighbors(style))
G2.add_edges_from([(style, n) for n in G.neighbors_iter(style)])
print len(G2)
G2.nodes()
37
['German-Style Bock',
'Belgian-Style Tripel',
'American Brett',
'Scottish-Style Ale',
'German-Style Marzen/Oktoberfest',
'English-Style India Pale Ale/IPA',
'German-Style Dunkel',
'Bohemian-Style Pilsener',
'Belgian-Style Lambic/Gueuze',
'American Amber Lager',
'Irish-Style Dry Stout',
'English-Style Brown Porter',
'German-Style Pilsener',
'English-Style Bitter',
'Fruit and Field Beer',
'Imperial India Pale Ale',
'Session Beer',
'Belgian-Style Pale Ale',
'Belgian-Style Saison',
'German-Style Hefeweizen',
'American Wheat',
'Belgian-Style Dubbel',
'English-Style Brown Ale',
'American Amber Ale',
'American Brown Ale',
'Vienna-Style Lager',
'American Pale Ale',
'European-Style Export',
'Belgian-Style Golden Strong Ale',
'Barrel-Aged Beer',
'German-Style Maibock',
'Belgian-Style Wit',
'English-Style Pale Ale/ESB',
'American Sour',
'English-Style Mild',
'Blonde Ale',
'German-Style Kolsch']
nx.draw_spring(G2,
node_color=COLORS[0],
node_size=200,
with_labels=True)
# plt.axis('equal')
for n in G.neighbors_iter('Belgian-Style Wit'):
print ('Belgian-Style Wit', n)
('Belgian-Style Wit', 'Bohemian-Style Pilsener')
('Belgian-Style Wit', 'Fruit and Field Beer')
('Belgian-Style Wit', 'German-Style Hefeweizen')
[('Belgian-Style Wit', n) for n in G.neighbors_iter('Belgian-Style Wit')]
[('Belgian-Style Wit', 'Bohemian-Style Pilsener'),
('Belgian-Style Wit', 'Fruit and Field Beer'),
('Belgian-Style Wit', 'German-Style Hefeweizen')]
PageRank
nx.pagerank(G)
{'American Amber Ale': 0.014582164068922921,
'American Amber Lager': 0.025391424521712974,
'American Barley Wine': 0.0020602941879801764,
'American Black Ale': 0.03524226870144604,
'American Brett': 0.02595062159582658,
'American Brown Ale': 0.018426950422189954,
'American Cream Ale': 0.0058283900725772265,
'American Imperial Porter': 0.003514312388015356,
'American Imperial Red Ale': 0.0029880065204832495,
'American Imperial Stout': 0.0020602941879801764,
'American India Pale Ale/IPA': 0.023727626131963907,
'American Pale Ale': 0.010514226095834273,
'American Sour': 0.05576906759108761,
'American Stout': 0.0020602941879801764,
'American Wheat': 0.02709132371840384,
'American-Style Wheat Wine Ale': 0.0028094467632845087,
'Baltic-Style Porter': 0.003274237915072287,
'Barrel-Aged Beer': 0.05209433396378796,
'Belgian-Style Blonde Ale': 0.0028563107818306375,
'Belgian-Style Dubbel': 0.059656549110350024,
'Belgian-Style Flanders': 0.0020602941879801764,
'Belgian-Style Fruit Lambic': 0.002644044296828293,
'Belgian-Style Golden Strong Ale': 0.009654698646410383,
'Belgian-Style Lambic/Gueuze': 0.0165306709842972,
'Belgian-Style Pale Ale': 0.021346693322413936,
'Belgian-Style Quadrupel': 0.006043600643162409,
'Belgian-Style Saison': 0.002644044296828293,
'Belgian-Style Tripel': 0.03326817397479022,
'Belgian-Style Wit': 0.03302477253969235,
'Berliner-Style Weisse': 0.004614446345485116,
'Blonde Ale': 0.006009608789874498,
'Bohemian-Style Pilsener': 0.011416945753781337,
'British-Style Barley Wine Ale': 0.0020602941879801764,
'California Common': 0.0020602941879801764,
'Chocolate Beer': 0.005131724883279979,
'Coffee Beer': 0.005265562714559706,
'English-Style Bitter': 0.011211835358211469,
'English-Style Brown Ale': 0.018996373601948575,
'English-Style Brown Porter': 0.03332469398697684,
'English-Style India Pale Ale/IPA': 0.012999718806943639,
'English-Style Mild': 0.018768276979798208,
'English-Style Oatmeal Stout': 0.0020602941879801764,
'English-Style Old Ale': 0.0095770010214148,
'English-Style Pale Ale/ESB': 0.009850525239380759,
'English-Style Sweet Stout (Milk Stout)': 0.015491522106287861,
'European-Style Export': 0.0020602941879801764,
'French-Style Biere de Garde': 0.0020602941879801764,
'Fruit and Field Beer': 0.05107155015442901,
'German-Style Bock': 0.016411283674223277,
'German-Style Brown/Altbier': 0.0020602941879801764,
'German-Style Doppelbock': 0.01492484922048327,
'German-Style Dunkel': 0.03378873176318905,
'German-Style Dunkelweizen': 0.0028563107818306375,
'German-Style Hefeweizen': 0.016976287891728965,
'German-Style Helles': 0.003807596085600591,
'German-Style Kolsch': 0.008609285690684169,
'German-Style Maibock': 0.01148588047023225,
'German-Style Marzen/Oktoberfest': 0.01293765353918299,
'German-Style Pilsener': 0.025135139197141255,
'German-Style Schwarzbier': 0.00431511378636796,
'German-Style Weizenbock': 0.002644044296828293,
'Gluten Free': 0.0020602941879801764,
'Herb and Spice Beer': 0.007018221684265235,
'Honey Beer': 0.006166855994626241,
'Imperial India Pale Ale': 0.012069630579080367,
'Irish-Style Dry Stout': 0.007957892512966488,
'Irish-Style Red': 0.0020602941879801764,
'Pumpkin Beer': 0.0020602941879801764,
'Robust Porter': 0.014723679453298067,
'Rye Beer': 0.0020602941879801764,
'Scotch Ale/Wee Heavy': 0.008993250912566685,
'Scottish-Style Ale': 0.013249163088915621,
'Session Beer': 0.005986237697278011,
'Smoke Beer': 0.0020602941879801764,
'Smoke Porter': 0.0020602941879801764,
'Specialty Beer': 0.0020602941879801764,
'Vienna-Style Lager': 0.026314145674263253}