How do I add an attribute name to an array? - python

I was wondering how to add an attribute to an array.
When I do
errors1 = pm.Uniform('errors', 0, 100, size = 7)
the name 'errors' is added.
but then when I do
errors2 = [errors1[1], errors1[3], errors1[6]]
I have no idea how to add that name, and because I didn't add it, when I try to create a model with errors2, I get an error, saying that it doesn't have an attribute name.
Here's my full code:
import pymc as pm
from matplotlib import pyplot as plt
from pymc.Matplot import plot as mcplot
import numpy as np
from matplotlib import rc
first_res = [-27.020,3.570,8.191,9.898,9.603,9.945,10.056]
second_res = [18.752, 12.450, 11.832]
v1 = pm.Uniform('v1', -30, 15)
v2 = pm.Uniform('v2', 0, 20)
errors1 = pm.Uniform('errors', 0, 100, size = 7)
errors2 = [errors1[1], errors1[3], errors1[6]] # doesn't have an attribute name
taus1 = 1/(errors1 ** 2)
taus2 = [taus1[1], taus1[3], taus1[6]]
first_dist = pm.Normal('first_dist', mu = v1, tau = taus1, value = first_res, observed = True)
second_dist= pm.Normal('second_dist', mu = v2, tau = taus2, value = second_res, observed = True)
model=pm.Model([first_dist, second_dist, errors1, taus1, v1, v2])
mcmc=pm.MCMC(model)
mcmc.sample(20000,10000)
mcplot(mcmc.trace("errors"))
plt.figure()
model2=pm.Model([second_dist, errors2, taus2, v2]) # since errors2 doesn't have an attribute name, I get an error
mcmc2=pm.MCMC(model2)
mcmc2.sample(20000,10000)
mcplot(mcmc2.trace('second_dist'))

PyMC2 has some magic that lets us operate on nodes like errors1 as if they are numpy arrays, but it doesn't always work as you might expect. In cases like this, you can define a deterministic node explicitly with the pm.Lambda, e.g.
errors2 = pm.Lambda('errors2', lambda errors1=errors1: [errors1[1],
errors1[3],
errors1[6]])

Just to clarify on some python concepts, the way you define errors2, it is a python list. lists do not have any name attribute. The attributes that have the elements of a list are not the same attributes of the list as a whole (as an object).
In fact, arrays do not have any name attribute either, and if errors1 does have a name attribute it is because it is pymc object, a distribution.
I think you have to define errors2 in more detail. Is it a uniform distribution? What is its relation to errors1, not in python, but statistically?

Related

Attribute Error: type object 'Object1' has no attribute 'mu'

This is a part of a code
class Object1:
def __init__(self):
mu = np.linspace(1.65, 1.8, num = 50)
self.mu=mu
I need to call mu attribute out of class.
What I tried:
a=getattr(Object1,'mu')
a=Object1.mu
Edit: I explain in a better way the problem and the solution.
I apologize for not posting all the code from the beginning, but I can't (I'll post a part of it) and because of that my question was misunderstood, I'll post the solution anyway and ask the question again.
import scipy.stats as sts
import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
class Object1:
def __init__(self):
"""
Variables and distributions.
Returns
-------
None.
"""
mu = np.linspace(1.65, 1.8, num = 50)
self.mu=mu
uniform_dist = sts.uniform.pdf(mu) + 1 #sneaky advanced note: I'm using the uniform distribution for clarity, but we can also make the beta distribution look completely flat by tweaking alpha and beta!
self.uniform_dist=uniform_dist
beta_dist = sts.beta.pdf(mu, 2, 5, loc = 1.65, scale = 0.2)
self.beta_dist =beta_dist
def normalization(self,distr):
return distr/distr.sum()
How I was calling the attributes:
a=Object1.mu
then I tried:
a=Object1().mu
Explanation: To call the normalization() method, I must call it on an object, and not on the class. That is what is failing, because when I do object.method(parameters), Python translates it to Class.method(object, parameters), making the object in question become self within the method. Calling it like Class.method(parameters), which is what I did, would result in a missing parameter in the call (python can't tell which one and assumes it's distr, but actually it was the first one, self).
Solution:
bayesian=Object1()
uniform_distribution=bayesian.uniform_dist
beta_distribution=bayesian.beta_dist
uniform_dist=bayesian.normalization(uniform_distribution)
beta_dist=bayesian.normalization(beta_distribution)
You can use the mu as a static variable
class Object1:
mu = np.linspace(1.65, 1.8, num = 50)
def __init__(self):
pass

'float' object has no attribute '__getitem__' Python error

When I run the code
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
# Initial conditions
def f_func(eta,y_in):
y_out = np.zeros(3)
y_out[0] = y_in[1]
y_out[1] = y_in[2]
y_out[2] = -y_in[0]*y_in[2]/2
return y_out
eta = np.linspace(0,8,100)
X0 = [0,0,0.33206]
X = odeint(f_func,X0,eta)
I get the error
'float' object has no attribute '__getitem__'
When I run the following MATLAB program, everything works OK. The MATLAB function ode45 is equivalent to Pythons' odeint.
main program:
clear
global beta
beta = 1;
initial_value = [0,0,1.2322];
eta = linspace(0,4,100)
[x_out, y_out] = ode45(#falkner_skan,eta,initial_value);
plot(x_out,y_out(:,2))
falkner_skan function:
function y_out = falkner_skan(x,y_in)
global beta
y_out(1,1) = y_in(2);
y_out(2,1) = y_in(3);
y_out(3,1) = -y_in(1)*y_in(3) - beta*(1-y_in(2)^2);
end
This and this and this thread does not seem to give me any guidance.
It seems as though y_in is not a list but a float value. The error rises because you're trying to get an item with obj[x] of an object which doesn't support it.
Looking at the documentation for odeint it says that the input function should take two arguments, the first being your data object and the second should be a float. Your implementation of f_func is therefore wrong.
NumPy has float 64 object which has item() function, np.float64(10.5).item()
I had the same issue. According to documentation for odeint, in f_func(eta,y_in), change the order of eta and y_in, i.e. write it as f_func(y_in, eta) or set the argument tfirst to be True.

Save data to VTK using Python and tvtk with more than one vector field

I'm trying to save three sets of vector quantities corresponding to the same structured grid (velocity, turbulence intensity and standard deviation of velocity fluctuations). Ideally, I'd like them to be a part of the same vtk file but so far I have only been able to get one of them into the file like so:
sg = tvtk.StructuredGrid(dimensions=x.shape, points=pts)
sg.point_data.vectors = U
sg.point_data.vectors.name = 'U'
write_data(sg, 'vtktestWake.vtk')
I've spent past few hours searching for an example of how to add more then one vector or scalar field but failed and so thought I'd ask here. Any guidance will be most appreciated.
Thanks,
Artur
After some digging around I found the following solution based on this and this example. You have to add the additional data field using the add_array method see:
from tvtk.api import tvtk, write_data
import numpy as np
data = np.random.random((3,3,3))
data2 = np.random.random((3,3,3))
i = tvtk.ImageData(spacing=(1, 1, 1), origin=(0, 0, 0))
i.point_data.scalars = data.ravel()
i.point_data.scalars.name = 'scalars'
i.dimensions = data.shape
# add second point data field
i.point_data.add_array(data2.ravel())
i.point_data.get_array(1).name = 'field2'
i.point_data.update()
write_data(i, 'vtktest.vtk')

mayavi - setting the [x,y,z] extent of an image programatically

I have some data that consists of several 2D images that I would like to render in specific [x,y,z] positions relative to one another using mayavi2 (v4.3.0).
From the documentation it seems that I should just be able to do this with mlab.imshow(). Unfortunately, mayavi throws an exception when I call imshow specifying the extent parameter (AttributeError: 'ImageActor' object has no attribute 'actor').
I also tried setting the x,y and z data directly by modifying im.mlab_source.x,y,z.... Weirdly, whilst this correctly changes the x and y extents, it does nothing to the z-position even though im.mlab_source.z clearly changes.
Here's a runnable example:
import numpy as np
from scipy.misc import lena
from mayavi import mlab
def normal_imshow(img=lena()):
return mlab.imshow(img,colormap='gray')
def set_extent(img=lena()):
return mlab.imshow(img,extent=[0,100,0,100,50,50],colormap='cool')
def set_xyz(img=lena()):
im = mlab.imshow(img,colormap='hot')
src = im.mlab_source
print 'Old z :',src.z
src.x = 100*(src.x - src.x.min())/(src.x.max() - src.x.min())
src.y = 100*(src.y - src.y.min())/(src.x.max() - src.y.min())
src.z[:] = 50
print 'New z :',src.z
return im
if __name__ == '__main__':
# this works
normal_imshow()
# # this fails (AttributeError)
# set_extent()
# weirdly, this seems to work for the x and y axes, but does not change
# the z-postion even though data.z does change
set_xyz()
Ok, it turns out that this is a known bug in mayavi. However, it is possible to change the orientation, position and scale of an ImageActor object after it has been created:
obj = mlab.imshow(img)
obj.actor.orientation = [0, 0, 0] # the required orientation
obj.actor.position = [0, 0, 0] # the required position
obj.actor.scale = [0, 0, 0] # the required scale

numpy and pytables issue (error: tuple index out of range)

I am new to python and pytables. Currently I am writing a project about clustering and KNN algorithm. That is what I have got.
********** code *****************
import numpy.random as npr
import numpy as np
step0: obtain the cluster
dtype = np.dtype('f4')
pnts_inds = np.arange(100)
npr.shuffle(pnts_inds)
pnts_inds = pnts_inds[:10]
pnts_inds = np.sort(pnts_inds)
for i,ind in enumerate(pnts_inds):
clusters[i] = pnts_obj[ind]
step1: save the result to a HDF5 file called clst_fn.h5
filters = tables.Filters(complevel = 1, complib = 'zlib')
clst_fobj = tables.openFile('clst_fn.h5', 'w')
clst_obj = clst_fobj.createCArray(clst_fobj.root, 'clusters',
tables.Atom.from_dtype(dtype), clusters.shape,
filters = filters)
clst_obj[:] = clusters
clst_fobj.close()
step2: other function
blabla
step3: load the cluster from clst_fn
pnts_fobj= tables.openFile('clst_fn.h5','r')
for pnts in pnts_fobj.walkNodes('/', classname = 'Array'):
break
#
step4: evoke another function (called knn). The function input argument is the data from pnts. I have checked the knn function individually. This function works well if the input is pnts = npr.rand(100,128)
def knn(pnts):
pnts = numpy.ascontiguousarray(pnts)
N = ctypes.c_uint(pnts.shape[0])
D = ctypes.c_uint(pnts.shape[1])
#
evoke knn using the cluster from clst_fn (see step 3)
knn(pnts)
********** end of code *****************
My problem now is that python is giving me a hard time by showing:
error: IndexError: tuple index out of range
This error comes from
"D = ctypes.c_uint(pnts.shape[1])" this line.
Obviously, there must be something wrong with the input argument. Any thought about fixing the problem? Thank you in advance.

Categories

Resources