Skippeh
Skippeh

Reputation: 25

Small change to code gives AttributeError (Python, Networkx)

I'm currently doing a project which involves using networkx to make an undirected graph with node positions based on a csv file and the class patches having various properties to indicate their positions, status and the indices of each nearest neighbour of each node. An emigration algorithm is then performed on this set of nodes.

I am currently wanting to scale up my code so I can have many more nodes, as this project is astronomical in nature. I was using regular Euclidean distances which is very slow for large populations due to quadratic scaling. I therefore employed a nearest neighbour algorithm to look just at nodes within some distance. I then made a csv of these, i.e. a csv of the indices of each nearest neighbour node. I am then trying to draw edges between these nodes in order for my algorithm to be performed upon the resulting graph.

However once I have made this change the next little block of code gets an AttributeError: 'numpy.int64' object has no attribute 'pos'.

My code is below and the Euclidean distance calculation is commented out for comparison. The block of code which is breaking is the one immediately after the edge drawing block, it is a sort of set-up for the algorithm which follows. I apologise for the stupid variable names - boba is the nearest neighbour node indices and bubu is the index of the node having edges drawn to it.

I'm stumped here because I don't know how the change is eve connected or why it would throw up this error.

nearand = np.genfromtxt('/Users/Skippy/nearand.csv', delimiter = ',',usecols=np.arange(0, 3)) # 3D cartesian co-ordinates of stars


density = 0.14 #Stellar density per cubic parsec
L = 100 # Size of box

Patches = int(0.056*density*L**3+15)


P_init = 0.0001   # Probability that a patch will be occupied at the beginning
Distance = 10 # An arbitrary parameter to determine which patches are     connected

xcoord = nearand[:,0]
ycoord = nearand[:,1]
zcoord = nearand[:,2]

bub = np.asarray(np.linspace(0, Patches, Patches, dtype = 'int'))
print bub
bobbington = np.asarray(np.genfromtxt('bobbington2.csv', delimiter = ',')) # csv of nearest neighbour node indices
bobbington0 = bobbington[:,0]
bobbington1 = bobbington[:,1]
bobbington2 = bobbington[:,2]
bobbington3 = bobbington[:,3]
bobbington4 = bobbington[:,4]
bobbington5 = bobbington[:,5]
bobbington6 = bobbington[:,6]
bobbington7 = bobbington[:,7]
bobbington8 = bobbington[:,8]
bobbington9 = bobbington[:,9]
bobbington10 = bobbington[:,10]
bobbington11 = bobbington[:,11]
bobbington12 = bobbington[:,12]


class patch:
    def __init__(self,status=0,pos=(0,0,0),boba = (0,0,0,0,0,0,0,0,0,0,0,0,0,),bubu = 0):
    self.status = status
    self.pos = pos
    self.boba = boba
    self.bubu = bubu
def __str__(self):
    return(str(self.status))

G = nx.Graph()

for i in xrange(Patches):

    Stat = 1 if np.random.uniform() < P_init else 0
    Pos  = (xcoord[i], ycoord[i], zcoord[i])
    Bob = (bobbington0[i],bobbington1[i],bobbington2[i],bobbington3[i],bobbington4[i],bobbington5[i],bobbington6[i],bobbington7[i],bobbington8[i],
bobbington9[i],bobbington10[i],bobbington11[i],bobbington12[i])
    Bubu = bub[i]
    G.add_node(patch(Stat,Pos,Bob,Bubu))

#for p1 in G.nodes():
    #for p2 in G.nodes():
        #Dist = np.sqrt((p1.pos[2] - p2.pos[2])**2 + (p1.pos[1]-p2.pos[1])**2+(p1.pos[0]-p2.pos[0])**2)
        #if Dist <= p1.dist:
        #if Dist <= Distance:
            #G.add_edge(p1,p2)

for i in G.nodes():
    edge1= (i.bubu,i.boba[0])
    edge2= (i.bubu,i.boba[1])
    edge3= (i.bubu,i.boba[2])
    edge4= (i.bubu,i.boba[3])
    edge5= (i.bubu,i.boba[4])
    edge6= (i.bubu,i.boba[5])
    edge7= (i.bubu,i.boba[6])
    edge8= (i.bubu,i.boba[7])
    edge9= (i.bubu,i.boba[8])
    edge10= (i.bubu,i.boba[9])
    edge11= (i.bubu,i.boba[10])
    edge12= (i.bubu,i.boba[11])
    edge13= (i.bubu,i.boba[12])

    G.add_edge(*edge1)
    G.add_edge(*edge2)
    G.add_edge(*edge3)
    G.add_edge(*edge4)
    G.add_edge(*edge5)
    G.add_edge(*edge6)
    G.add_edge(*edge7)
    G.add_edge(*edge8)
    G.add_edge(*edge9)
    G.add_edge(*edge10)
    G.add_edge(*edge11)
    G.add_edge(*edge12)
    G.add_edge(*edge13)

pos = {} # THE BIT CAUSING ISSUES
for i in G.nodes():
    pos[i] = i.pos


occup = [n.status for n in G]   # THIS ALSO HAS NO 'status' ATTRIBUTE ERROR

Time = [0]
Occupancy = [np.sum([n.status for n in G])/float(Patches)]

##Then algorithm goes here##

Can anyone see what the issue is?

Upvotes: 0

Views: 131

Answers (1)

Joel
Joel

Reputation: 23887

In your code, the variable bub appears to me to be a numpy array.

In each patch you create when doing G.add_node(patch(...)), the argument Bubu is set to be an entry from bub. So it's a number. Then for that patch, self.bubu is a number.

When you add edges, you're adding edges from i.bubu to i.boba[some index]. So since i.bubu is a number you're creating edges from those numbers to something else. This will cause networkx to add nodes which are those numbers.

So prior to entering the loop for i in G.nodes(): pos[i] = i.pos many of the nodes in G are numbers rather than patches.

For these numbers, it does not make sense to refer to number.pos. That's something you've defined for your patch class.

Upvotes: 2

Related Questions