I have a 500x500 array and I am trying to write a variable called "coordinate" that will pick out each value and then apply it to a function but I keep getting the output,
AttributeError Traceback (most recent call last)
/home/graham/<ipython-input-17-cc6ce0649eda> in <module>()
31 pass
32
---> 33 finished_array = rand_array_color(rand_array)
34
35 finished_image = Image.fromarray(finished_array)
/home/graham/<ipython-input-17-cc6ce0649eda> in rand_array_color(rand_array)
23 from PIL import Image
24 for ii in numpy.nditer(rand_array):
---> 25 coordinate = tuple(map(int, rand_image[ii,:]))
26 if ii < 128:
27 print "false"
/usr/lib/python2.7/dist-packages/PIL/Image.pyc in __getattr__(self, name)
510 new['data'] = self.tostring()
511 return new
--> 512 raise AttributeError(name)
513
514 ##
AttributeError: __getitem__
Here is my code
from PIL import Image
from numpy import random
im = Image.open('/home/graham/Desktop/Experiment/gwarner/labeled_photos/photos/003030.png')
rand_array = numpy.random.randint(255, size=(500,500)).astype('uint8')
rand_image = Image.fromarray(rand_array)
def rand_array_color(rand_array):
from PIL import Image
for ii in numpy.nditer(rand_array):
coordinate = tuple(map(int, rand_image[ii,:]))
if ii < 128:
newvalue = rand_image.putpixel(coordinate(a,ii), im.getpixel(coordinate(a,ii)))
return newvalue
else:
pass
finished_array = rand_array_color(rand_array)
I've also been fiddling around with another version of coordinate,
coordinate = tuple(int(rand_array[ii,0]),int(rand_array[ii,1])
but it just returns,
NameError: name 'ii' is not defined
Can anyone tell me how to fix one of these or recommend another one that will work?
The reason you cannot get the iith row of rand_image using rand_image[ii,:] is because rand_image is a PIL Image object, and doesn't have the same indexing access that an array has. If you want to get the iith row, you must use rand_array[ii] (I've left off the trailing colon ,: isn't required)
This appears to be similar to your
another version of coordinate
which should work because you're using the array instead of the Image. My guess is that you've not replaced it in exactly the same place as the first version, perhaps somewhere outside of the for ii in ... loop, because ii is only properly defined within that loop.
As you've defined it, coordinate is not a function, it's a tuple of length 2. But you call it as a function when you write coordinate(a, ii). Rather, you probably just want to use coordinate there (I'm not sure what a is supposed to be.
The function .putpixel does not return anything, so that when you say:
newvalue = rand_image.putpixel(...)
newvalue will be None (the 'empty' object in python). Perhaps you want to do this:
rand_image.putpixel(...)
return rand_image
without setting the newvalue and trying to return it, but instead changing the pixel in the rand_image and returning the new rand_image.
As a side note, you should not call int() on a numpy array, instead, if you want the type of each element in the array to be int, you should either use .astype as you did above, or initiate it as an int in the first place. Once it starts as an int, it should stay that way unless you cast it somehow (which you haven't done in this script).
As a final note this process could probably be done a lot faster using numpy (not using pure python loops) but I'm not sure exactly what you're trying to do. If you edit your question to explain a little bit what you're trying to do so that I can read the code with some context, I could help. For example, what is a supposed to be in the newvalue = ... line?
Related
I am completely new to Panda3D on Python and trying to edit a 3D mesh in-place to move its vertices following the user's inputs.
I am using the GeomVertexRewriter or GeomVertexReader + GeomVertexWriter APIs (I tried both), as suggested in the Panda3D documentation here.
However I could not create any GeomVertexWriter (or GeomVertexRewriter which herits from both GeomVertexReader and GeomVertexWriter) object without encountering the following error:
TypeError: Arguments must match:
GeomVertexWriter()
GeomVertexWriter(GeomVertexArrayData array_data)
GeomVertexWriter(GeomVertexData vertex_data)
GeomVertexWriter(Thread current_thread)
GeomVertexWriter(GeomVertexData vertex_data, const InternalName name, Thread current_thread)
GeomVertexWriter(GeomVertexArrayData array_data, int column, Thread current_thread)
GeomVertexWriter(GeomVertexArrayData array_data, Thread current_thread)
GeomVertexWriter(GeomVertexData vertex_data, Thread current_thread)
The error does not happen when I create a GeomVertexReader, and it seems to work perfectly.
Also, my vdata is of the correct type (<class 'panda3d.core.GeomVertexData'>) and prints correctly too (shortened version below):
CatMesh2
949 rows.
Array 0 (0000018310B6A3E0, [ vertex(3f) normal(3f) ]):
row 0:
vertex 1.57086 8.22246 0.487809
normal 0.672279 0.738758 0.0477129
row 1:
vertex 1.69762 8.07273 1.88392
normal 0.748853 0.662674 0.00910493
[...]
row 948:
texcoord 0.249509 0.530177 0
It seems that everywhere I searched, the only way this constructor is ever called is with the very same syntax GeomVertexWriter(vdata, 'vertex') (or 'texcoord'), so I don't really see why this type error occurs.
I tried the following code (that doesn't work):
vertex = GeomVertexRewriter(vdata, 'vertex')
while not vertex.isAtEnd():
v = vertex.getData3()
vertex.setData3(v[0], v[1], 0.0)
>>> File "...\src\geometry_processing.py", line 6, in editVertexData
vertex = GeomVertexRewriter(vdata, 'vertex')
TypeError: Arguments must match:
[...]
Same goes for this one:
vertexW = GeomVertexWriter(vdata, 'vertex')
vertexR = GeomVertexReader(vdata, 'vertex')
v = vertexR.getData3()
vertexW.setData3(v[0], v[1], newVal)
It also happens when I replace 'vertex' with 'texcoord'.
The reader version however works fine:
vertexR = GeomVertexReader(vdata, 'vertex')
v = vertexR.getData3()
print(v)
>>> LVecBase3f(1.57086, 8.22246, 0.487809)
Has anyone ever encountered this error? I have no idea why it occurs even though I am doing the same thing as in the examples in the documentation and in other places. If it was not my mistake, could it be that the vdata from the model I am using is the issue?
How did you obtain the GeomVertexData object? It's possible that you have a "const" version of this object, such as obtained from geom.getVertexData(), but you need a non-const version, such as obtained from geom.modifyVertexData().
I am trying to compare an array value with the previous and the next one using the below code but i get the too many indices in array error, which I would like to bypass, but I dont know how.
spikes=print(M.V[0])
#iterate in list of M.V[0] with three iterators to find the spikes
for i,x in enumerate(M.V[0]):
if (i>=1):
if x[i-1]<x[i] & x[i]>x[i+1] & x[i]>25*mV:
spikes+=1
print(spikes)
and I get this error:
IndexError Traceback (most recent call last)
<ipython-input-24-76d7b392071a> in <module>
3 for i,x in enumerate(M.V[0]):
4 if (i>=1):
----> 5 if x[i-1]<x[i] & x[i]>x[i+1] & x[i]>25*mV:
6 spikes+=1
7 print(spikes)
~/anaconda3/lib/python3.6/site-packages/brian2/units/fundamentalunits.py in __getitem__(self, key)
1306 single integer or a tuple of integers) retain their unit.
1307 '''
-> 1308 return Quantity(np.ndarray.__getitem__(self, key), self.dim)
1309
1310 def __getslice__(self, start, end):
IndexError: too many indices for array
Do note that M.V[0] is an array by itself
You said that "M.V[0] is an array by itself". However, you need to say more about it. Probably M is StateMonitor object detailed in https://brian2.readthedocs.io/en/stable/user/recording.html#recording-spikes . Is this correct ?
If so, you need to give full and minimal code in order to understand your details. For instance, what is your neuron model inside NeuronGroup object? More importantly, instead of finding spike event on your own, why don't you use SpikeMonitor class which extremely ease what you are planning ?
SpikeMonitor class in Brian2 : https://brian2.readthedocs.io/en/stable/reference/brian2.monitors.spikemonitor.SpikeMonitor.html
I have the following Python code which throws the error in the title:
# calculate number of all ROI pixels inside defined(hsv -) color range
pts2 = cv2.findNonZero(mask_final)
non_zero_pixel = int(len(pts2))
Similarly here as well:
# calculate number of all ROI pixels inside defined(bgr -) color range "black"
pts = cv2.findNonZero(mask_black)
black_pixel = int(len(pts))
I translated this piece of code from its C++ version which did work without an error:
// Calculate number of all ROI pixels inside defined (hsv-)color range
vector<Point> pts2;
findNonZero(mask_final, pts2);
double non_zero_pixel = static_cast<int>(pts2.size());
I don't know why the Python version makes a problem whereas C++ version does not.
Any thoughts?
EDIT: Exception details:
--------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-119-f76eaba94311> in <module>()
28
29 if __name__ == "__main__":
---> 30 main() # pass the list of arguments from the command line
<ipython-input-119-f76eaba94311> in main()
16
17 # detect screws
---> 18 detectScrews(img)
19
20 for j in range(len(screw_radiuses)):
<ipython-input-118-4c225e9bc794> in detectScrews(img)
80 # calculate number of all ROI pixels inside defined(bgr -) color range "black"
81 pts = cv2.findNonZero(mask_black)
---> 82 black_pixel = int(len(pts))
83
84 # if number of black pixel is lower than threshold
TypeError: object of type 'NoneType' has no len()
It means that there are no non-zero elements in mask_final.
This shows the same error:
print(len(cv2.findNonZero(np.zeros([3,3], np.uint8))))
Why does not the C++ version do the same? I am running it on the same image. Python one fails, C++ one passes. It's weird
Python returns the type None, which is the typical Python way of specifying there is nothing. You could for example then write (very Pythonic):
if cv2.findNonZero(np.zeros([3,3], np.uint8)) is None:
print('I didnt find any zeros')
Languages like C++ don't have a distinct type that has the same meaning. It does have a Null, but it's essentially just a 0. Which means that if the function returns a Null, it could be mistaken for the element at index 0. The None in Python is its own, and doesn't mean 0 at all.
I keep getting the error
TypeError: 'numpy.float64' object is not callable"
I thought I have been careful to not repeat variables within functions etc., but this error keeps popping up whenever I try to execute
scipy.integrate.odeint(doublepend,fnaught,t,args=(L,9.81,M))
I'm not sure what's going on. See below for the rest of the code.
import scipy as scipy
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math as mt
import numpy as np
def singlepend(thetarray,time,Length,gravity,mass):
import numpy as np
theta,delatheta=y
dtheta=np.zeros_like(y)
#theta solved
dtheta[0]=deltatheta
dtheta[1]=(g/L)*np.sin(theta)
return dy
def doublepend(y,tim,Langles,g,Mangles):
import numpy as np
thetanaught,deltatheta,phinaught,deltaphi=y
mtheta,mphi=Mangles
print mtheta
Ltheta,Lphi=Langles
dy=np.zeros_like(y)
#theta solved
dy[0]=deltatheta
dy[1]=-mphi*np.sin(thetanaught-phinaught)*((deltatheta**2)*np.cos(thetanaught-phinaught)+(deltaphi**2)*Lphi/Lphi)/(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught)))\
+mphi*g*np.sin(phinaught)*np.cos(thetanaught-phinaught)/(Ltheta*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught))))\
-(mtheta+mphi)*g*np.sin(thetanaught)/(Ltheta*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught))))
#phi solved
dy[2]=deltaphi
dy[3]=mphi*(deltaphi**2)*np.sin(thetanaught-phinaught)/(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught)))\
+(mtheta+mphi)*g*np.sin(thetanaught)*np.cos(thetanaught-phinaught)/(Lphi*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught))))\
(mtheta+mphi)*Ltheta*(deltatheta**2)*np.sin(thetanaught-phinaught)/(Lphi*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos*(thetanaught-phinaught))))\
-(mtheta+mphi)*g*np.sin(phinaught)/(Lphi*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught))))
return dy
#initial conditions
m1=1
m2=1
L1=1
L2=1
M=(m1,m2)
L=(L1,L2)
phi1naught=np.array(np.pi/2)
phi2naught=np.array(np.pi/2)
phi1dotnaught=np.array(0)
phi2dotnaught=np.array(0)
fnaught=(phi1naught,phi1dotnaught,phi2naught,phi2dotnaught)
t=np.linspace(0,20,100001)
f=scipy.integrate.odeint(doublepend,fnaught,t,args=(L,9.81,M))
I realize that I do not need to import numpy multiple times. I am designing those functions to become a small library of functions to be used later as examples.
We need to see some of the stack, but even with that it may be hard to identify which variable is giving problems.
The error means that some code is trying to do something like x(args), i.e. use x as a function. But contrary to expectations x is a number, not a function.
The solution is to identify what variable is causing the problem, and trace that back to your code.
Offhand the inputs to odeint look fine:
odeint(doublepend,fnaught,t,args=(L,9.81,M))
Of these only the first, doublepend has to be a function. It appears to be that, but I'd couple check just before the odeint call.
fnaught is the initial condition. You appear to create a tuple of values. I'd make an array, but I think odeint will do that automatically.
t is an array
args gets a tuple of numbers. Those get passed to your doublepend.
Does doublepend(fnaught, 0, L, 9.81, M) run? What does it return?
The other answer thinks the problem lies in that doublepend function. A stack trace would make that clear, as would the above test calc.
In [13]: doublepend(fnaught, 0, L, 9.81, M)
1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-f8aa70c3f962> in <module>()
----> 1 doublepend(fnaught, 0, L, 9.81, M)
<ipython-input-10-3c95347f392b> in doublepend(y, tim, Langles, g, Mangles)
13 #phi solved
14 dy[2]=deltaphi
---> 15 dy[3]=mphi*(deltaphi**2)*np.sin(thetanaught-phinaught)/(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught))) +(mtheta+mphi)*g*np.sin(thetanaught)*np.cos(thetanaught-phinaught)/(Lphi*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught)))) (mtheta+mphi)*Ltheta*(deltatheta**2)*np.sin(thetanaught-phinaught)/(Lphi*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos*(thetanaught-phinaught)))) -(mtheta+mphi)*g*np.sin(phinaught)/(Lphi*(mtheta+mphi*(1-np.cos(thetanaught-phinaught)*np.cos(thetanaught-phinaught))))
16
17 return dy
TypeError: 'numpy.float64' object is not callable
OK - the error is somewhere in that long and ugly dy[3] expression. Break it up, and figure out where you are using () for something that is a number rather than function.
This looks suspicious
np.cos(thetanaught-phinaught)))) (mtheta+mphi)
np.cos() evaluates to a number, and the next (methata...)looks like an function call. It runs if I delete the last 2 lines of dy[3]. Something is missing at that line continuation`.
I'm trying to import nodes into Neo4j in a batch. But when I try to execute it, it throws an error: List indices must be integers, not float. I don't really understand which listitems, I do have floats, but these are cast to strings...
Partial code:
graph_db = neo4j.GraphDatabaseService("http://127.0.0.1:7474/db/data/")
batch = neo4j.WriteBatch(graph_db)
for ngram, one_grams in data.items():
ngram_rank = int(one_grams['_rank'])
ngram_prob = '%.16f' % float(one_grams['_prob'])
ngram_id = 'a'+str(n)
ngram_node = batch.create(node({"word": ngram, "rank": str(ngram_rank), "prob": str(ngram_prob)}))
for one_gram, two_grams in one_grams.items():
one_rank = int(two_grams['_rank'])
one_prob = '%.16f' % float(two_grams['_prob'])
one_node = batch.create(node({"word": one_gram, "rank": str(one_rank), "prob": one_prob}))
batch.create(rel((ngram_node, "FOLLOWED_BY", one_node))) #line 81 throwing error
results = batch.submit()
Full traceback
Traceback (most recent call last):
File "Ngram_neo4j.py", line 81, in probability_items
batch.create(rel((ngram_node, "FOLLOWED_BY", one_node))),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2692, in create
uri = self._uri_for(entity.start_node, "relationships"),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2537, in _uri_for
uri = "{{{0}}}".format(self.find(resource)),
File "virtenv\\lib\\site-packages\\py2neo\\neo4j.py", line 2525, in find
for i, req in pendulate(self._requests):,
File "virtenv\\lib\\site-packages\\py2neo\\util.py", line 161, in pendulate
yield index, collection[index],
TypeError: list indices must be integers, not float
running neo4j 2.0, py2neo 1.6.1, Windows 7/64bit, python 3.3/64bit
--EDIT--
Did some testing, but the error is located in the referencing to nodes.
oversimplified sample code:
for key, dict in data.items(): #string, dictionary
batch = neo4j.WriteBatch(graph_db)
three_gram_node = batch.create(node({"word": key}))
pprint(three_gram_node)
batch.add_labels(three_gram_node, "3gram") # must be int, not float
for k,v in dict.items(): #string, string
four_gram_node = batch.create(node({"word": k}))
batch.create_path(three_gram_node, "FOLLOWED_BY", four_gram_node)
# cannot cast node from BatchRequest obj
batch.submit()
When a node is created batch.create(node({props})), the pprint returns a P2Neo.neo4j. batchrequest object.
At the line add_labels(), it gives the same error as when trying to create a relation: List indices must be integers, not float.
At the batch.create_path() line it throws an error saying it can't cast a node from a P2Neo.neo4j. batchrequest object.
I'm trying the dirty-debug now to understand the indices.
--Dirty Debug Edit--
I've been meddling around with the pendulate(collection) function.
Although I don't really understand how it fits in, and how it's used, the following is happening:
Whenever it hits an uneven number, it gets cast to a float (which is weird, since count - ((i + 1) / 2), where i is an uneven number.) This float then throws the list indices error. Some prints:
count: 3
i= 0
index: 0
(int)index: 0
i= 1 # i = uneven
index: 2.0 # a float appears
(int)index: 2 # this is a safe cast
This results in the list indices error. This also happens when i=0. As this is a common case, I made an additional if() to circumvent the code (possible speedup?) Although I've not unit tested this, it seems that we can safely cast index to an int...
The pendulate function as used:
def pendulate(collection):
count = len(collection)
print("count: ", count)
for i in range(count):
print("i=", i)
if i == 0:
index = 0
elif i % 2 == 0:
index = i / 2
else:
index = count - ((i + 1) / 2)
print("index:", index)
index = int(index)
print("(int)index:", index)
yield index, collection[index]
soft debug : print ngram_node and one_node to see what they contains
dirty debug : modify File "virtenv\lib\site-packages\py2neo\util.py", line 161, add a line before :
print index
You are accessing a collection (a Python list given the traceback), so, for sure, index must be an integer :)
printing it will probably help you to understand why exception raised
(Don't forget to remove your dirty debug afterwards ;))
While it is currently possible for WriteBatch objects to be executed multiple times with edits in between, it is inadvisable to use them in this way and this will be restricted in the next version of py2neo. This is because objects created during one execution will not be available during a subsequent execution and it is not easy to detect when this is being requested.
Without looking back at the underlying code, I'm unsure why you are seeing this exact error but I would suggest refactoring your code so that each WriteBatch creation is paired with one and only one execution call (submit). You can probably achieve this by putting your batch creation within your outer loop and moving your submit call out of the inner loop into the outer loop as well.