Graph Construction and feature engineering

Load library


In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import networkx as nx
import pygraphviz as pgv
import pydot as pyd
from networkx.drawing.nx_agraph import graphviz_layout
from networkx.drawing.nx_agraph import write_dot

Load data


In [142]:
%%time
edges = pd.read_csv('../data/edges.csv').drop('Unnamed: 0',1)
nodes = pd.read_csv('../data/nodes.csv').drop('Unnamed: 0',1)
rogues = pd.read_csv('../data/rogues.csv')


CPU times: user 32.4 s, sys: 4.42 s, total: 36.9 s
Wall time: 36.9 s

Graph generation & analysis

Build proper edge array


In [3]:
%%time
#Simple way (non parallel computing)
edge_array = []
for i in range(0,1000000):
    edge_array.append((edges['from'][i],edges['to'][i],{'value':edges['value'][i],'time':edges['timestamp'][i],'hash':edges['hash'][i]}))


CPU times: user 2min 16s, sys: 996 ms, total: 2min 17s
Wall time: 2min 17s

Generate a MultiDigraph with networkx and edge array


In [5]:
%%time
TG=nx.MultiDiGraph()
TG.add_weighted_edges_from(edge_array)


CPU times: user 5.21 s, sys: 216 ms, total: 5.42 s
Wall time: 5.4 s

In [6]:
%%time
# Network Characteristics
print 'Number of nodes:', TG.number_of_nodes() 
print 'Number of edges:', TG.number_of_edges() 
print 'Number of connected components:', nx.number_connected_components(TG.to_undirected())

# Degree
degree_sequence = TG.degree().values()
degree_out_sequence = TG.out_degree().values()
degree_in_sequence = TG.in_degree().values()

print "Min degree ", np.min(degree_sequence)
print "Max degree ", np.max(degree_sequence)
print "Median degree ", np.median(degree_sequence)
print "Mean degree ", np.mean(degree_sequence)

print "Min degree IN", np.min(degree_in_sequence)
print "Max degree IN", np.max(degree_in_sequence)
print "Median degree IN", np.median(degree_in_sequence)
print "Mean degree IN", np.mean(degree_in_sequence)

print "Min degree OUT", np.min(degree_out_sequence)
print "Max degree OUT", np.max(degree_out_sequence)
print "Median degree OUT", np.median(degree_out_sequence)
print "Mean degree OUT", np.mean(degree_out_sequence)


Number of nodes: 29355
Number of edges: 1000000
Number of connected components: 96
Min degree  1
Max degree  232035
Median degree  3.0
Mean degree  68.131493783
Min degree IN 0
Max degree IN 222682
Median degree IN 1.0
Mean degree IN 34.0657468915
Min degree OUT 0
Max degree OUT 137271
Median degree OUT 1.0
Mean degree OUT 34.0657468915
CPU times: user 21.4 s, sys: 552 ms, total: 21.9 s
Wall time: 21.9 s

In [8]:
%%time
# Degree distribution
y=nx.degree_histogram(TG)
plt.figure(1)
plt.loglog(y,'b-',marker='o')
plt.ylabel("Frequency")
plt.xlabel("Degree")
plt.draw()
plt.show()


CPU times: user 1.34 s, sys: 552 ms, total: 1.9 s
Wall time: 1.27 s

Features Engineering


In [9]:
#New dataframe for feature engineering
df = pd.DataFrame()
df['nodes']=TG.nodes()

Features description

  • Roman (I-XXI) : Node intrinsec charateristics feature set
  • Arabic (1-5) : Neighbors behaviours feature set
  • Greek (α-ω) : External data features
# Description Variable
I Degree total_degree
II Degree in degree_in
III Degree out degree_out
IV Number of unique predecessors unique_predecessors
V Number of unique successors unique_successors
VI Mean ether amount in incoming transactions mean_value_in
VII Mean ether amount in outgoing transactions mean_value_out
VIII Std ether amount in incoming transactions std_value_in
IX Std ether amount in outgoing transactions std_value_out
X Ratio of the number of incoming transactions to the number of unique timestamps ratio_in_timestamp
XI Ratio of the number of outgoing transactions to the number of unique timestamps ratio_out_timestamp
XII Frequency of incoming transactions frequency_in
XIII Frequency of outgoing transactions frequency_out
XIV Ether balance of the node balance
XVI Average velocity in mean_velocity_out
XVII Average velocity out mean_velocity_out
XVIII Std velocity in std_velocity_in
XIX Std velocity out std_velocity_out
XX Average acceleration in mean_acceleration_in
XXI Average acceleration out mean_acceleration_out
α Min path to a rogue node min_path_to_rogue
β Min path from a rogue node min_path_from_rogue
δ Amount of ether on the min path to a rogue node amount_to_rogue
ε Amount of ether on the min path from a rogue node amount_from_rogue
1 Average neighbours velocity
2 Average neighbours acceleration -


Add total degree [I]


In [10]:
df['total_degree']=df['nodes'].map(lambda x: TG.degree(x))


Add degree in and degree out [II] [III]


In [11]:
df['degree_in']=df['nodes'].map(lambda x: TG.in_degree(x))
df['degree_out']=df['nodes'].map(lambda x: TG.out_degree(x))


Add unique predecessors and unique successors (must be < degree_in and out) [IV][V]


In [12]:
df['unique_successors']=df['nodes'].map(lambda x: len((TG.successors(x))))
df['unique_predecessors']=df['nodes'].map(lambda x: len((TG.predecessors(x))))


Add mean ether value going in the node [VI]

Write a function


In [13]:
def get_mean_value_in(node):
    '''
    Return the mean value of all the in transactions of a given node
    '''
    #Get the in edges list
    edges = TG.in_edges_iter(node, keys=False, data=True)
    #Build a list of all the values of the in edges list
    values=[]
    for edge in edges:
        values.append(float(edge[2]['weight']['value']))
    #Compute the mean of this list
    mean = np.average(values)
    
    return mean

In [14]:
%%time
#Add the feature
df['mean_value_in']=df['nodes'].map(lambda x: get_mean_value_in(x))


/usr/local/lib/python2.7/dist-packages/numpy/core/_methods.py:59: RuntimeWarning: Mean of empty slice.
  warnings.warn("Mean of empty slice.", RuntimeWarning)
CPU times: user 2.11 s, sys: 28 ms, total: 2.14 s
Wall time: 2.1 s


Add mean ether value going out the node [VII]


In [15]:
#Write a function
def get_mean_value_out(node):
    '''
    Return the mean value of all the out transactions of a given node
    '''
    #Get the out edges list
    edges = TG.out_edges_iter(node, keys=False, data=True)
    #Build a list of all the values of the out edges list
    values=[]
    for edge in edges:
        values.append(float(edge[2]['weight']['value']))
    #Compute the mean of this list
    mean = np.average(values)
    return mean

In [16]:
%%time
#Add the feature
df['mean_value_out']=df['nodes'].map(lambda x: get_mean_value_out(x))


CPU times: user 1.97 s, sys: 12 ms, total: 1.98 s
Wall time: 1.97 s


Add std ether value going in the node [VIII]


In [17]:
#Write a function
def get_std_value_in(node):
    '''
    Return the std value of all the in transactions of a given node
    '''
    #Get the in edges list
    edges = TG.in_edges_iter(node, keys=False, data=True)
    #Build a list of all the values of the in edges list
    values=[]
    for edge in edges:
        values.append(float(edge[2]['weight']['value']))
    #Compute the std of this list
    std = np.std(values)
    
    return std

In [18]:
%%time
#Add the feature
df['std_value_in']=df['nodes'].map(lambda x: get_std_value_in(x))


/usr/local/lib/python2.7/dist-packages/numpy/core/_methods.py:82: RuntimeWarning: Degrees of freedom <= 0 for slice
  warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
CPU times: user 2.9 s, sys: 28 ms, total: 2.92 s
Wall time: 2.9 s


Add std ether value going out the node [IX]


In [19]:
#Write a function
def get_std_value_out(node):
    '''
    Return the std value of all the out transactions of a given node
    '''
    #Get the out edges list
    edges = TG.out_edges_iter(node, keys=False, data=True)
    #Build a list of all the values of the out edges list
    values=[]
    for edge in edges:
        values.append(float(edge[2]['weight']['value']))
    #Compute the std of this list
    std = np.std(values)
    
    return std

In [20]:
%%time
#Add the feature
df['std_value_out']=df['nodes'].map(lambda x: get_std_value_out(x))


CPU times: user 3.7 s, sys: 8 ms, total: 3.71 s
Wall time: 3.69 s


Add the ratio of the number of incoming transactions to the number of unique timestamps for those transactions [X]


In [21]:
#Write a function
def get_ratio_in_timestamp(node):
    '''
    Return the ratio between the number of incoming transaction to the number of unique timestamp for these transactions
    '''
    #Get the list of incoming transactions
    edges = TG.in_edges(node,keys=False, data=True)
    #Build the list of timestamps
    timestamps=[]
    for edge in edges:
        timestamps.append(edge[2]['weight']['time'])
    #Compute the ratio
    unique_time = float(len(np.unique(timestamps)))
    transactions = float(len(edges))
    
    if unique_time !=0:
        ratio = transactions / unique_time
    else:
        ratio = np.nan
    
    return ratio

In [22]:
%%time
#Add the feature
df['ratio_in_timestamp']=df['nodes'].map(lambda x: get_ratio_in_timestamp(x))


CPU times: user 2.08 s, sys: 20 ms, total: 2.1 s
Wall time: 2.1 s


Add the ratio of the number of outgoing transactions to the number of unique timestamps for those transactions [XI]


In [23]:
#Write a function
def get_ratio_out_timestamp(node):
    '''
    Return the ratio between the number of incoming transaction to the number of unique timestamp for these transactions
    '''
    #Get the list of outgoing transactions
    edges = TG.out_edges(node,keys=False, data=True)
    #Build the list of timestamps
    timestamps=[]
    for edge in edges:
        timestamps.append(edge[2]['weight']['time'])
    #Compute the ratio
    unique_time = float(len(np.unique(timestamps)))
    transactions = float(len(edges))
    
    if unique_time !=0:
        ratio = transactions / unique_time
    else:
        ratio = np.nan
    
    return ratio

In [24]:
%%time
#Add the feature
df['ratio_out_timestamp']=df['nodes'].map(lambda x: get_ratio_out_timestamp(x))


CPU times: user 3.69 s, sys: 4 ms, total: 3.69 s
Wall time: 3.69 s


the incoming transaction frequency for the user (#in transactions / max date - min date) [XII]


In [25]:
#write function
def get_in_frequency(node):
    '''
    Return the incoming transaction frequency for the user (#in transactions / max date - min date)
    '''
    #Get the list of incoming transactions
    edges = TG.in_edges(node,keys=False, data=True)
    #Build the list of timestamps
    timestamps=[]
    for edge in edges:
        timestamps.append(edge[2]['weight']['time'])
    #Build the delta in seconds
    date = pd.to_datetime(pd.Series(timestamps))
    dt = date.max()-date.min()
    #deltaseconds = dt.item().total_seconds()
    
    if dt.total_seconds()!=0:
        ratio = len(edges)/dt.total_seconds()
    else:
        ratio = np.nan
    
    return ratio

In [26]:
%%time
#Add the feature
df['frequency_in']=df['nodes'].map(lambda x: get_in_frequency(x))


CPU times: user 13.5 s, sys: 12 ms, total: 13.5 s
Wall time: 13.5 s


the outgoing transaction frequency for the user (#out transactions / max date - min date) [XIII]


In [27]:
#write function
def get_out_frequency(node):
    '''
    Return the outgoing transaction frequency for the user (#in transactions / max date - min date)
    '''
    #Get the list of incoming transactions
    edges = TG.out_edges(node,keys=False, data=True)
    #Build the list of timestamps
    timestamps=[]
    for edge in edges:
        timestamps.append(edge[2]['weight']['time'])
    #Build the delta in seconds
    date = pd.to_datetime(pd.Series(timestamps))
    dt = date.max()-date.min()
    #deltaseconds = dt.item().total_seconds()
    
    if dt.total_seconds()!=0:
        ratio = len(edges)/dt.total_seconds()
    else:
        ratio = np.nan
    
    return ratio

In [28]:
%%time
#Add the feature
df['frequency_out']=df['nodes'].map(lambda x: get_out_frequency(x))


CPU times: user 13.9 s, sys: 24 ms, total: 14 s
Wall time: 14 s


ether balance [XIV]


In [29]:
#write function
def get_balance(node):
    '''
    Return the balance (in wei) of a given node
    '''
    #Get edges in and edges out
    edges_in = TG.in_edges(node,keys=False, data=True)
    edges_out = TG.out_edges(node,keys=False, data=True)
    #Build value in array and value out array
    values_in=[]
    for edge in edges_in:
        values_in.append(float(edge[2]['weight']['value']))
    values_out=[]
    for edge in edges_out:
        values_out.append(float(edge[2]['weight']['value']))
    #Compute balance
    balance = np.sum(values_in)-np.sum(values_out)
    
    return balance

In [30]:
%%time
#Add the feature
df['balance']=df['nodes'].map(lambda x: get_balance(x))


CPU times: user 5.67 s, sys: 20 ms, total: 5.69 s
Wall time: 5.68 s


Average Velocity In [XV]


In [102]:
#write function
def get_mean_velocity_in(node):
    """
    Return the average ether velocitiy incoming into the node in wei/s
    """
    #Get edges in collection
    edges_in = TG.in_edges(node,keys=False, data=True)
    values_in=[]
    timestamps=[]
    #Collect values and timestamps
    for edge in edges_in:
        values_in.append(float(edge[2]['weight']['value']))
        timestamps.append(edge[2]['weight']['time'])
    #Create Velocity list
    velocities = []
    #Convert date str to datetime
    dates = pd.to_datetime(pd.Series(timestamps))
    #Build the velocity array 
    for i in range(1,(len(edges_in)-1)):
        if dates[i+1]!=dates[i-1]:
            velocity = np.absolute(values_in[i+1]-values_in[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            velocities.append(velocity)
    
    #Return the velocities average
    return np.average(np.absolute(velocities))

In [103]:
%%time
#Add the feature
df['mean_velocity_in']=df['nodes'].map(lambda x: get_mean_velocity_in(x))


CPU times: user 2min 6s, sys: 412 ms, total: 2min 6s
Wall time: 2min 6s


Average Velocity Out [XVI]


In [96]:
#write function
def get_mean_velocity_out(node):
    """
    Return the average ether velocitiy outgoing from the node in wei/s
    """
    #Get edges out collection
    edges_out = TG.out_edges(node,keys=False, data=True)
    values_out=[]
    timestamps=[]
    #Collect values and timestamps
    for edge in edges_out:
        values_out.append(float(edge[2]['weight']['value']))
        timestamps.append(edge[2]['weight']['time'])
    #Create Velocity list
    velocities = []
    #Convert date str to datetime
    dates = pd.to_datetime(pd.Series(timestamps))
    #Build the velocity array 
    for i in range(1,(len(edges_out)-1)):
        if dates[i+1]!=dates[i-1]:
            velocity = np.absolute(values_out[i+1]-values_out[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            velocities.append(velocity)
    
    #Return the velocities average
    return np.average(np.absolute(velocities))

In [97]:
%%time
#Add the feature
df['mean_velocity_out']=df['nodes'].map(lambda x: get_mean_velocity_out(x))


CPU times: user 2min 11s, sys: 432 ms, total: 2min 12s
Wall time: 2min 11s


Std Velocity In [XVII]


In [98]:
#write function
def get_std_velocity_in(node):
    """
    Return the std ether velocitiy incoming into the node in wei/s
    """
    #Get edges in collection
    edges_in = TG.in_edges(node,keys=False, data=True)
    values_in=[]
    timestamps=[]
    #Collect values and timestamps
    for edge in edges_in:
        values_in.append(float(edge[2]['weight']['value']))
        timestamps.append(edge[2]['weight']['time'])
    #Create Velocity list
    velocities = []
    #Convert date str to datetime
    dates = pd.to_datetime(pd.Series(timestamps))
    #Build the velocity array 
    for i in range(0,(len(edges_in)-1)):
        if dates[i+1]!=dates[i-1]:
            velocity = np.absolute(values_in[i+1]-values_in[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            velocities.append(velocity)
    
    #Return the velocities average
    return np.std(np.absolute(velocities))

In [99]:
%%time
#Add the feature
df['std_velocity_in']=df['nodes'].map(lambda x: get_std_velocity_in(x))


CPU times: user 2min 10s, sys: 428 ms, total: 2min 10s
Wall time: 2min 10s


Std Velocity Out [XVIII]


In [100]:
#write function
def get_std_velocity_out(node):
    """
    Return the std ether velocitiy outgoing from the node in wei/s
    """
    #Get edges out collection
    edges_out = TG.out_edges(node,keys=False, data=True)
    values_out=[]
    timestamps=[]
    #Collect values and timestamps
    for edge in edges_out:
        values_out.append(float(edge[2]['weight']['value']))
        timestamps.append(edge[2]['weight']['time'])
    #Create Velocity list
    velocities = []
    #Convert date str to datetime
    dates = pd.to_datetime(pd.Series(timestamps))
    #Build the velocity array 
    for i in range(0,(len(edges_out)-1)):
        if dates[i+1]!=dates[i]:
            velocity = np.absolute(values_out[i+1]-values_out[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            velocities.append(velocity)
    
    #Return the velocities average
    return np.std(np.absolute(velocities))

In [76]:
%%time
#Add the feature
df['std_velocity_out']=df['nodes'].map(lambda x: get_std_velocity_out(x))


CPU times: user 2min 11s, sys: 404 ms, total: 2min 11s
Wall time: 2min 11s


Average Acceleration In [XIX]


In [113]:
#write function
def get_mean_acceleration_in(node):
    """
    Return the average ether acceleration incoming into the node in wei.s-2
    """
    #Get edges in collection
    edges_in = TG.in_edges(node,keys=False, data=True)
    values_in=[]
    timestamps=[]
    #Collect values and timestamps
    for edge in edges_in:
        values_in.append(float(edge[2]['weight']['value']))
        timestamps.append(edge[2]['weight']['time'])
    #Create Velocity list
    velocities = []
    #Convert date str to datetime
    dates = pd.to_datetime(pd.Series(timestamps))
    #Build the velocity array 
    for i in range(1,(len(edges_in)-1)):
        if dates[i+1]!=dates[i-1]:
            velocity = np.absolute(values_in[i+1]-values_in[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            velocities.append(velocity)
    #Make sure we have abs ... 
    velocities=np.absolute(velocities)
    #Velocities range from 1 to N-1 (no 0 and N)
    #Accelerations range from 2 to N-2
    #Build the acceleration array
    accelerations=[]
    for i in range(1,(len(velocities)-1)):
        if dates[i+1]!=dates[i-1]:
            acceleration = np.absolute(velocities[i+1]-velocities[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            accelerations.append(acceleration)
    #Return the velocities average
    return np.average(np.absolute(accelerations))

In [118]:
%%time
#Add the feature
df['mean_acceleration_in']=df['nodes'].map(lambda x: get_mean_acceleration_in(x))


CPU times: user 3min 59s, sys: 800 ms, total: 3min 59s
Wall time: 3min 59s


Average Velocity Out [XX]


In [121]:
#write function
def get_mean_acceleration_out(node):
    """
    Return the average ether acceleration outgoing into the node in wei.s-2
    """
    #Get edges out collection
    edges_out = TG.out_edges(node,keys=False, data=True)
    values_out=[]
    timestamps=[]
    #Collect values and timestamps
    for edge in edges_out:
        values_out.append(float(edge[2]['weight']['value']))
        timestamps.append(edge[2]['weight']['time'])
    #Create Velocity list
    velocities = []
    #Convert date str to datetime
    dates = pd.to_datetime(pd.Series(timestamps))
    #Build the velocity array 
    for i in range(1,(len(edges_out)-1)):
        if dates[i+1]!=dates[i-1]:
            velocity = np.absolute(values_out[i+1]-values_out[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            velocities.append(velocity)
    #Make sure we have abs ... 
    velocities=np.absolute(velocities)
    #Velocities range from 1 to N-1 (no 0 and N)
    #Accelerations range from 2 to N-2
    #Build the acceleration array
    accelerations=[]
    for i in range(1,(len(velocities)-1)):
        if dates[i+1]!=dates[i-1]:
            acceleration = np.absolute(velocities[i+1]-velocities[i-1])/(dates[i+1]-dates[i-1]).total_seconds()
            accelerations.append(acceleration)
    #Return the velocities average
    return np.average(np.absolute(accelerations))

In [122]:
%%time
#Add the feature
df['mean_acceleration_out']=df['nodes'].map(lambda x: get_mean_acceleration_out(x))


CPU times: user 4min 3s, sys: 972 ms, total: 4min 4s
Wall time: 4min 3s


Getting Rogue nodes


In [149]:
rogues = pd.read_csv("../data/rogues.csv")
rogues_id = np.array(rogues['id'])
fake_rogues = ['0x223294182093bfc6b11e8ef5722d496f066036c2','0xec1ebac9da3430213281c80fa6d46378341a96ae','0xe6447ae67346b5fb7ebd65ebfc4c7e6521b21f8a']


Min path to a rogue node [α]


In [171]:
#write function
def min_path_to_rogue(node,rogues):
    paths_lengths=[]
    for rogue in rogues:
        if nx.has_path(TG,node,rogue):
            paths_lengths.append(len(nx.shortest_path(TG,node,rogue)))
    if len(paths_lengths)!=0:
        return np.min(paths_lengths)
    else:
        return np.nan

In [172]:
%%time
#Add the feature
df['min_path_to_rogue']=df['nodes'].map(lambda x: min_path_to_rogue(x,fake_rogues))


CPU times: user 32.4 s, sys: 8 ms, total: 32.4 s
Wall time: 32.4 s


Min path from a rogue node [β]


In [174]:
#write function
def min_path_from_rogue(node,rogues):
    paths_lengths=[]
    for rogue in rogues:
        if nx.has_path(TG,rogue,node):
            paths_lengths.append(len(nx.shortest_path(TG,rogue,node)))
    if len(paths_lengths)!=0:
        return np.min(paths_lengths)
    else:
        return np.nan

In [175]:
%%time
#Add the feature
df['min_path_from_rogue']=df['nodes'].map(lambda x: min_path_from_rogue(x,fake_rogues))


CPU times: user 10.9 s, sys: 0 ns, total: 10.9 s
Wall time: 10.9 s


Amount of ether flown from node to the closest rogue [δ]


Amount of ether flown to node from the closest rogue [ε]


In [147]:
df.tail(100)


Out[147]:
nodes total_degree degree_in degree_out unique_successors unique_predecessors mean_value_in mean_value_out std_value_in std_value_out ... ratio_out_timestamp frequency_in frequency_out balance mean_velocity_in mean_velocity_out std_velocity_in std_velocity_out mean_acceleration_in mean_acceleration_out
29255 0xa18f9051c9bebb19f5a3efec110cb3e2d7b5dea3 87 81 6 3 1 5.081216e+18 6.856500e+19 2.190355e+17 7.558188e+19 ... 1.000000 3.009393e-05 2.038859e-06 1.885345e+17 2.749866e+12 1.784526e+14 2.025455e+13 1.876069e+14 8.583029e+07 4.095948e+06
29256 0x4e4b72116e77b2a56ae9ac941a8c55add89291d3 3 1 2 2 1 8.710120e+16 4.680690e+16 0.000000e+00 4.680690e+16 ... 1.000000 NaN 7.142857e-02 -6.512600e+15 NaN 3.343350e+15 NaN 0.000000e+00 NaN NaN
29257 0x2ff160c44f72a299b5ec2d71e28ce5446d2fcbaf 1 0 1 1 0 NaN 3.590000e+20 NaN 0.000000e+00 ... 1.000000 NaN NaN -3.590000e+20 NaN NaN NaN NaN NaN NaN
29258 0xb197aa5a56c22724a62ff2100f961c2a3a30aaab 1321 241 1080 1 3 1.745630e+18 3.884406e+17 1.690018e+18 1.055521e+18 ... 1.865285 2.297390e-05 1.029570e-04 1.181083e+18 3.452528e+12 2.531432e+14 7.613778e+15 4.281922e+15 3.795076e+07 8.553826e+11
29259 0x85989c7372d7dfb1cee01762442415bd5eb39a7d 6 4 2 1 2 3.003801e+18 6.000000e+18 2.605654e+18 6.000000e+18 ... 1.000000 4.144219e-05 1.574803e-02 1.520309e+16 7.894324e+13 9.448819e+16 1.268852e+14 0.000000e+00 NaN NaN
29260 0x2dd325fdffb97b19995284afa5abdb574a1df16a 8 0 8 1 0 NaN 6.237500e+19 NaN 3.173302e+19 ... 1.000000 NaN 2.010097e-06 -4.990000e+20 NaN 1.086725e+15 NaN 2.202223e+15 NaN 6.653602e+09
29261 0x2feea0fa3fe12e800fea4916c2349e243d9b18cc 1 1 0 0 1 2.000000e+21 NaN 0.000000e+00 NaN ... NaN NaN NaN 2.000000e+21 NaN NaN NaN NaN NaN NaN
29262 0xe6447ae67346b5fb7ebd65ebfc4c7e6521b21f8a 1 1 0 0 1 1.900000e+17 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.900000e+17 NaN NaN NaN NaN NaN NaN
29263 0x93258255b37c7f58f4b10673a932dd3afd90f4f2 1 0 1 1 0 NaN 9.999989e+20 NaN 0.000000e+00 ... 1.000000 NaN NaN -9.999989e+20 NaN NaN NaN NaN NaN NaN
29264 0xf13ffcb7fb5d21929db6b86cfc18c0ba1ad618b8 8 2 6 5 1 1.937368e+19 3.213777e+18 1.737368e+19 4.156823e+18 ... 1.000000 3.248114e-06 1.374227e-05 1.946471e+19 NaN 1.706526e+15 0.000000e+00 3.180818e+15 NaN 7.758636e+08
29265 0x61c9d63697b8ea3c387ccb3e693f02d4f597b763 3 1 2 2 1 6.105080e+16 3.378170e+16 0.000000e+00 3.378170e+16 ... 1.000000 NaN 2.127660e-02 -6.512600e+15 NaN 7.187596e+14 NaN 0.000000e+00 NaN NaN
29266 0x123d670b2b4685f55fc8dfecc898b052b45068f3 2 1 1 1 1 1.000000e+18 9.000000e+17 0.000000e+00 0.000000e+00 ... 1.000000 NaN NaN 1.000000e+17 NaN NaN NaN NaN NaN NaN
29267 0x6e6a31b5283b8447dd969af47edb4d30a7d83b39 1 1 0 0 1 1.100052e+16 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.100052e+16 NaN NaN NaN NaN NaN NaN
29268 0x4c1e93e64c9f87885721bea4c9db6859328c6958 10 5 5 1 1 7.453734e+19 7.453629e+19 6.939299e+19 6.939299e+19 ... 1.000000 6.127826e-05 6.134292e-05 5.250000e+15 5.609014e+15 9.625482e+15 1.426635e+16 1.391191e+16 4.618118e+09 4.859422e+09
29269 0x174a13614f77576edb636942ff4e736943a33d44 1 1 0 0 1 1.100001e+16 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.100001e+16 NaN NaN NaN NaN NaN NaN
29270 0xbc8273ed604aba5019315a4cff00d621a497145f 2 1 1 1 1 5.000000e+15 3.000000e+15 0.000000e+00 0.000000e+00 ... 1.000000 NaN NaN 2.000000e+15 NaN NaN NaN NaN NaN NaN
29271 0x0053b80823b7a02861c80c9ae83435b32475bfef 1 1 0 0 1 4.712464e+18 NaN 0.000000e+00 NaN ... NaN NaN NaN 4.712464e+18 NaN NaN NaN NaN NaN NaN
29272 0x57c8d40977ab299da4e51ba1b376a5600bdd10e4 1 1 0 0 1 1.000000e+18 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.000000e+18 NaN NaN NaN NaN NaN NaN
29273 0xff1a845b44851f97825ecd99e54cd0b41e234de1 2 1 1 1 1 7.974870e+19 7.974765e+19 0.000000e+00 0.000000e+00 ... 1.000000 NaN NaN 1.050000e+15 NaN NaN NaN NaN NaN NaN
29274 0xec1ebac9da3430213281c80fa6d46378341a96ae 6 4 2 1 2 3.210822e+17 6.410882e+17 4.336343e+17 4.762336e+17 ... 1.000000 5.441292e-07 2.850851e-07 2.152500e+15 7.504457e+10 1.357671e+11 3.534112e+10 0.000000e+00 NaN NaN
29275 0xfe367f318b68f2caef12c50bbe5336b7d87481d4 31 31 0 0 3 8.871880e+18 NaN 3.521867e+19 NaN ... NaN 1.042742e-05 NaN 2.750283e+20 4.500536e+13 NaN 2.522670e+13 NaN 4.703676e+09 NaN
29276 0x81c294cbb1360edbe5b9b00743aff8ebf499076c 3222 2985 237 1 108 1.369678e+19 1.725088e+20 4.274106e+19 1.907080e+20 ... 1.000000 4.270212e-04 3.390422e-05 2.796628e+17 1.032114e+14 1.098266e+17 2.828258e+15 4.211994e+17 1.278394e+12 3.302181e+10
29277 0x7afebc14e64ef2c14259532bae47038055daf904 3 2 1 1 1 6.000000e+15 1.000000e+00 0.000000e+00 0.000000e+00 ... 1.000000 2.298851e-03 NaN 1.200000e+16 NaN NaN 0.000000e+00 NaN NaN NaN
29278 0xf084eabafbdec8489139e086da1e50930c670873 3 1 2 2 1 1.261768e+17 6.634470e+16 0.000000e+00 6.634470e+16 ... 1.000000 NaN 7.142857e-02 -6.512600e+15 NaN 4.738907e+15 NaN 0.000000e+00 NaN NaN
29279 0x18795830b5efa1edfc185b4f2b1aae939fa87239 1 1 0 0 1 1.200000e+16 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.200000e+16 NaN NaN NaN NaN NaN NaN
29280 0x52f710b22483e809475381bccc36203ac020bafc 53 50 3 1 1 4.485782e+18 9.016627e+18 3.461683e+18 5.969141e+18 ... 1.000000 2.225703e-05 1.202872e-05 1.972392e+20 1.205385e+13 6.926200e+13 4.506553e+13 3.009858e+13 1.234395e+08 NaN
29281 0x93b56d516644adda311d995af1c5d33acee80bdc 240 206 34 2 1 2.743917e+19 1.662477e+20 1.496484e+19 1.432877e+20 ... 1.062500 2.323066e-05 3.751645e-06 4.590461e+16 4.182242e+13 1.298959e+16 1.618222e+14 5.323356e+16 4.174616e+08 7.178599e+13
29282 0xae062c448618643075de7a0030342dced63dbad7 1 0 1 1 0 NaN 8.259000e+20 NaN 0.000000e+00 ... 1.000000 NaN NaN -8.259000e+20 NaN NaN NaN NaN NaN NaN
29283 0x9c5cc111092c122116f1a85f4ee31408741a7d2f 1 0 1 1 0 NaN 4.915000e+20 NaN 0.000000e+00 ... 1.000000 NaN NaN -4.915000e+20 NaN NaN NaN NaN NaN NaN
29284 0x640b354f60e101a6f2ed54105e3ed80d0bd4619f 5 5 0 0 2 1.047309e+18 NaN 4.737468e+17 NaN ... NaN 1.230270e-05 NaN 5.236543e+18 2.174624e+12 NaN 2.184958e+12 NaN 1.307613e+07 NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
29325 0x53d0ee755204858890edaece8474b9489a5be611 2 1 1 1 1 3.727527e+18 3.726477e+18 0.000000e+00 0.000000e+00 ... 1.000000 NaN NaN 1.050000e+15 NaN NaN NaN NaN NaN NaN
29326 0x5eb29be794cc425659ce205c7574d158dfa6fb15 10 10 0 0 3 1.127289e+18 NaN 4.768876e+17 NaN ... NaN 4.808885e-06 NaN 1.127289e+19 1.855126e+12 NaN 4.362889e+12 NaN 4.996952e+06 NaN
29327 0xcb0cc129c71e46ace639da1acaa98b901a26f4e6 4 4 0 0 1 5.000000e+15 NaN 8.660254e+15 NaN ... NaN 6.611570e-03 NaN 2.000000e+16 2.212389e+13 NaN 4.405650e+13 NaN NaN NaN
29328 0xc87b2895ad1086df3c7f96b565ece1003c520976 362 207 155 1 1 5.558063e+17 7.363662e+17 1.373320e+17 2.708900e+17 ... 1.000000 2.139991e-05 1.616834e-05 9.151448e+17 1.068908e+12 2.328547e+12 1.875885e+12 2.489284e+12 8.598539e+06 8.936604e+06
29329 0x8a8a68c2a6387bf5fd93f8ac1b4b546c05a80fc6 99 91 8 1 2 3.807705e+17 3.625000e+18 1.613937e+17 2.079513e+18 ... 1.000000 1.859042e-05 2.657138e-06 5.650112e+18 1.306995e+12 3.973088e+14 5.469036e+12 9.587493e+14 1.254435e+07 3.176693e+06
29330 0x8143a7314e1e89e35885e25c35362aca01b0f1ff 4 2 2 1 1 3.750000e+20 3.749987e+20 3.650000e+20 3.650000e+20 ... 1.000000 1.972387e-03 2.030457e-03 2.500200e+15 NaN 7.411168e+17 0.000000e+00 0.000000e+00 NaN NaN
29331 0xe3712701619ca7623c55db3a0ad30e867db0168b 8 4 4 1 1 1.169617e+19 4.925000e+18 1.084121e+19 8.127846e+18 ... 1.000000 1.825871e-06 9.261442e-07 2.708468e+19 5.111803e+13 1.992860e+13 1.054527e+16 2.811265e+13 NaN NaN
29332 0xeef16575c4bb1682c3a9731db20e3c041f951e3c 70 68 2 2 4 1.352061e+18 4.596400e+19 4.077030e+18 4.595295e+19 ... 1.000000 1.231731e-05 1.165243e-05 1.214597e+16 5.360918e+12 5.354636e+14 5.804929e+14 0.000000e+00 2.248460e+07 NaN
29333 0xf44f8551ace933720712c5c491cdb6f2f951736c 2 0 2 1 0 NaN 1.999995e+21 NaN 1.989995e+21 ... 1.000000 NaN 2.739726e-04 -3.999990e+21 NaN 5.452041e+17 NaN 0.000000e+00 NaN NaN
29334 0x7a0f8dfecec6563badeb284902022351414d37e5 1 1 0 0 1 1.000000e+17 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.000000e+17 NaN NaN NaN NaN NaN NaN
29335 0x223294182093bfc6b11e8ef5722d496f066036c2 4 4 0 0 1 0.000000e+00 NaN 0.000000e+00 NaN ... NaN 2.159244e-04 NaN 0.000000e+00 0.000000e+00 NaN 0.000000e+00 NaN NaN NaN
29336 0x1bc527e33dabcdda75c3f5d1df697d9d7656619c 20 10 10 1 1 5.000000e+18 4.998950e+18 0.000000e+00 0.000000e+00 ... 1.000000 1.864810e-06 1.865016e-06 1.050000e+16 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
29337 0x9bf35642f3f7d3eda9a2629b4377b6cf5393bb8f 1 1 0 0 1 1.500000e+16 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.500000e+16 NaN NaN NaN NaN NaN NaN
29338 0xd7a7528c0357f1b64b2bf93ebd63e817f2e731b8 4 2 2 1 1 1.660060e+19 1.659934e+19 1.361060e+19 1.361060e+19 ... 1.000000 4.301075e-03 3.610108e-03 2.520000e+15 NaN 4.913574e+16 0.000000e+00 0.000000e+00 NaN NaN
29339 0x3e8c40498098dd81d00f8bca8744a0053c82079a 7 2 5 2 2 3.500031e+21 1.400011e+21 4.999680e+20 1.714993e+21 ... 1.000000 1.262626e-03 1.933488e-03 5.900000e+15 NaN 1.239675e+19 0.000000e+00 2.010806e+19 NaN 3.299638e+14
29340 0x9e8816c04a6873d5f5e63d988d6fe550007ca6f7 3 1 2 2 1 1.463968e+20 7.319734e+19 0.000000e+00 5.319734e+19 ... 1.000000 NaN 4.067131e-07 2.100000e+15 NaN 2.163606e+13 NaN 0.000000e+00 NaN NaN
29341 0x6432ea0c129180e37c908e7ea06c6ebadb230dbc 1 1 0 0 1 1.100035e+16 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.100035e+16 NaN NaN NaN NaN NaN NaN
29342 0xca9aa6c60347a93e3a50854a02e2d2b64c3e38ca 1 1 0 0 1 1.200055e+16 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.200055e+16 NaN NaN NaN NaN NaN NaN
29343 0xbaecc9abb79a87eb7e7d5942ffe42c34e8c8abc7 178 124 54 1 1 1.042356e+18 2.373990e+18 3.732871e+16 1.033897e+18 ... 1.000000 1.472670e-04 6.463273e-05 1.056637e+18 2.996254e+12 7.674499e+13 6.891104e+12 4.810586e+13 2.256276e+08 8.298787e+08
29344 0x4833e265c3f52d93f70030db9214075f91b9bdfc 1 1 0 0 1 0.000000e+00 NaN 0.000000e+00 NaN ... NaN NaN NaN 0.000000e+00 NaN NaN NaN NaN NaN NaN
29345 0x4c3e95cc3957d252ce0bf0c87d5b4f2234672e70 2 0 2 1 0 NaN 1.249500e+21 NaN 1.150500e+21 ... 1.000000 NaN 5.949725e-05 -2.499000e+21 NaN 6.845158e+16 NaN 0.000000e+00 NaN NaN
29346 0x5cb22a640d3bf627592bef808bf35f8224fdf440 3 1 2 2 1 6.105080e+16 3.378170e+16 0.000000e+00 3.378170e+16 ... 1.000000 NaN 1.333333e-01 -6.512600e+15 NaN 4.504227e+15 NaN 0.000000e+00 NaN NaN
29347 0x0073d800c98c9feb45662b10a7ca7debd635005f 1 0 1 1 0 NaN 4.998950e+18 NaN 0.000000e+00 ... 1.000000 NaN NaN -4.998950e+18 NaN NaN NaN NaN NaN NaN
29348 0x48b1d63ea6fb6f97d041f929feb15eeef558d43b 11 2 9 1 1 9.000000e+17 1.000000e+00 1.000000e+17 0.000000e+00 ... 1.000000 3.053081e-06 9.872751e-04 1.800000e+18 NaN 0.000000e+00 0.000000e+00 0.000000e+00 NaN 0.000000e+00
29349 0x9014c1c66c473e2441cc8f1b101594b1a05bd08b 16 8 8 1 7 1.830625e+20 1.830612e+20 2.428978e+20 2.428978e+20 ... 1.000000 8.039601e-07 8.055893e-07 1.000087e+16 1.084969e+16 3.850077e+16 4.784062e+16 6.296069e+16 1.093068e+12 2.998971e+12
29350 0xe9696f31041900c16e866bd8d87a4f930cecef5a 1 1 0 0 1 1.200052e+16 NaN 0.000000e+00 NaN ... NaN NaN NaN 1.200052e+16 NaN NaN NaN NaN NaN NaN
29351 0x0bd8488cc0adb4960e708944dc5fe6f7cebe948f 3 3 0 0 1 1.000000e+06 NaN 1.414214e+06 NaN ... NaN 2.325581e-02 NaN 3.000000e+06 2.325581e+04 NaN 5.769231e+04 NaN NaN NaN
29352 0x11485c5f164d6a67a72eee9093b2581d1c304094 1 1 0 0 1 0.000000e+00 NaN 0.000000e+00 NaN ... NaN NaN NaN 0.000000e+00 NaN NaN NaN NaN NaN NaN
29353 0x1a8081993a09aba50b338aa1a98716f847966e46 3 3 0 0 1 0.000000e+00 NaN 0.000000e+00 NaN ... NaN 4.918033e-02 NaN 0.000000e+00 0.000000e+00 NaN 0.000000e+00 NaN NaN NaN
29354 0x156b0240f9199ae7f846a94da767e2fe47463584 15 8 7 2 1 9.801093e+18 1.120020e+19 6.654617e+18 6.062411e+18 ... 1.000000 4.109563e-06 5.953186e-06 7.350000e+15 1.302203e+13 9.254840e+12 1.486454e+13 1.750989e+13 9.770564e+07 1.165723e+08

100 rows × 21 columns


In [143]:
len(nx.shortest_path(TG,source="0x61c9d63697b8ea3c387ccb3e693f02d4f597b763",target="0xbaecc9abb79a87eb7e7d5942ffe42c34e8c8abc7"))


Out[143]:
8

In [144]:
len(nx.shortest_path(TG,source="0xbaecc9abb79a87eb7e7d5942ffe42c34e8c8abc7",target="0x61c9d63697b8ea3c387ccb3e693f02d4f597b763"))


Out[144]:
15

In [ ]: