numpy vertical function :'float' object is not subscriptable - python

I have a numpy arrary:
import numpy as np
pval=np.array([[0., 0.,0., 0., 0.,0., 0., 0.],
[0., 0., 0., 0., 0.,0., 0., 0.]])
And a vectorized function:
def getnpx(age):
return pval[0]+age
vgetnpx = np.frompyfunc(getnpx, 1, 1)
vgetnpx(1)
The output:
array([1., 1., 1., 1., 1., 1., 1., 1.])
However if I want to set a variable for pval:
def getnpx(mt,age):
return mt[0]+age
vgetnpx = np.frompyfunc(getnpx, 2, 1)
vgetnpx(pval,1)
I received an error:
TypeError: 'float' object is not subscriptable
What is the correct way to set a variable for pval ?Any friend can help?

I don't see why you are trying to use frompyfunc. That's for passing array arguments to a function that only takes scalar inputs.
In [97]: pval=np.array([[0., 0.,0., 0., 0.,0., 0., 0.],
...: [0., 0., 0., 0., 0.,0., 0., 0.]])
In the first case you use global pval, and use just 1 age value. No need to frompyfunc:
In [98]: pval[0]+1
Out[98]: array([1., 1., 1., 1., 1., 1., 1., 1.])
And if you want to pass pval as argument, just do:
In [99]: def foo(mt,age):
...: return mt[0]+age
...:
In [100]: foo(pval,1)
Out[100]: array([1., 1., 1., 1., 1., 1., 1., 1.])
You gave a link to an earlier question that I answered. The sticky point in that case was that your function returned an array that could vary in size. I showed how to use it with a list comprehension. I also showed how to tweak vectorize so it would happy returning an object dtype result. Alternatively use frompyfunc to return that object. In all those cases the function argument was a scalar, a single number.
If your goal is to add a different age to each row of pval, just do:
In [102]: pval + np.array([[1],[2]])
Out[102]:
array([[1., 1., 1., 1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2., 2., 2., 2.]])

Related

How to make a row of a matrix be the column of another matrix in an elegant way with Python? [duplicate]

How could the following MATLAB code be written using NumPy?
A = zeros(5, 100);
x = ones(5,1);
A(:,1) = x;
Assigning to rows seems to work easily, but I couldn't find an example of assigning an array to a column of another array.
Use a[:,1] = x[:,0]. You need x[:,0] to select the column of x as a single numpy array. If you have the choice of how to format x, it's better to not make it a 2-dimensional array in the first place, but just a regular (row) array:
>>> a
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> x = numpy.ones(5)
>>> x
array([ 1., 1., 1., 1., 1.])
>>> a[:,1] = x
>>> a
array([[ 0., 1., 0.],
[ 0., 1., 0.],
[ 0., 1., 0.],
[ 0., 1., 0.],
[ 0., 1., 0.]])
>>> A = np.zeros((5,100))
>>> x = np.ones((5,1))
>>> A[:,:1] = x

Row-wise Logical operation on numpy.ndarray

I have an numpy.ndarray in the following format:
array([[ 0., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 1., 0., 0.],
...,
[ 1., 0., 0., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
and I want to apply the XOR logical operator on elements of each row. i.e. I want an output like in the following format:
[[0.],
[1.],
[1.],
...,
[1],
[0],
[0]]
How can I do this in Python ? I know about np.logical_xor but I do not know that how I can use it efficiently.
Thanks !!!
Use .reduce:
import numpy as np
arr = np.array([[0., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 1., 0., 0.],
[1., 0., 0., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
res = np.logical_xor.reduce(arr, 1).astype(np.int32)
print(res)
Output
[0 1 1 0 0 0]
The function np.logical_xor is an ufunc, as such it has 4 methods, from the documentation (emphasis mine):
All ufuncs have four methods. However, these methods only make sense on scalar ufuncs that take two input arguments and return one
output argument. Attempting to call these methods on other ufuncs will
cause a ValueError. The reduce-like methods all take an axis keyword,
a dtype keyword, and an out keyword, and the arrays must all have
dimension >= 1.
To apply an ufunc along an axis use .reduce:
Reduces array’s dimension by one, by applying ufunc along one axis.

minimize runtime for numpy array manipulation

I have an 2 dimensional array with np.shape(input)=(a,b) and that looks like
input=array[array_1[0,0,0,1,0,1,2,0,3,3,2,...,entry_b],...array_a[1,0,0,1,2,2,0,3,1,3,3,...,entry_b]]
Now I want to create an array np.shape(output)=(a,b,b) in which every entry that had the same value in the input get the value 1 and 0 otherwise
for example:
input=[[1,0,0,0,1,2]]
output=[array([[1., 0., 0., 0., 1., 0.],
[0., 1., 1., 1., 0., 0.],
[0., 1., 1., 1., 0., 0.],
[0., 1., 1., 1., 0., 0.],
[1., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 1.]])]
My code so far is looking like:
def get_matrix(svdata,padding_size):
List=[]
for k in svdata:
matrix=np.zeros((padding_size,padding_size))
for l in range(padding_size):
for m in range(padding_size):
if k[l]==k[m]:
matrix[l][m]=1
List.append(matrix)
return List
But it takes 2:30 min for an input array of shape (2000,256). How can I become more effiecient by using built in numpy solutions?
res = input[:,:,None]==input[:,None,:]
Should give boolean (a,b,b) array
res = res.astype(int)
to get a 0/1 array
You're trying to create the array y where y[i,j,k] is 1 if input[i,j] == input[i, k]. At least that's what I think you're trying to do.
So y = input[:,:,None] == input[:,None,:] will give you a boolean array. You can then convert that to np.dtype('float64') using astype(...) if you want.

Inexplicable behavior when using vlen with h5py

I am using h5py to build a dataset. Since I want to store arrays with different #of rows dimension, I use the h5py special_type vlen. However, I experience behavior I can't explain, maybe you can me help in understanding what is happening:
>>>> import h5py
>>>> import numpy as np
>>>> fp = h5py.File(datasource_fname, mode='w')
>>>> dt = h5py.special_dtype(vlen=np.dtype('float32'))
>>>> train_targets = fp.create_dataset('target_sequence', shape=(9549, 5,), dtype=dt)
>>>> test
Out[130]:
array([[ 0., 1., 1., 1., 0., 1., 1., 0., 1., 0., 0.],
[ 1., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1.]])
>>>> train_targets[0] = test
>>>> train_targets[0]
Out[138]:
array([ array([ 0., 1., 0., 0., 0., 1., 0., 0., 0., 0., 1.], dtype=float32),
array([ 1., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0.], dtype=float32),
array([ 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0.], dtype=float32),
array([ 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0.], dtype=float32),
array([ 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0.], dtype=float32)], dtype=object)
I do expect the train_targets[0] to be of this shape, however I can't recognize the rows in my array. They seem to be totally jumbled about, however it is consistent. By which I mean that every time I try the above code, train_targets[0] looks the same.
To clarify: the first element in my train_targets, in this case test, has shape (5,11), however the second element might be of shape (5,38) which is why I use vlen.
Thank you for your help
Mat
I think
train_targets[0] = test
has stored your (11,5) array as an F ordered array in a row of train_targets. According to the (9549,5) shape, that's a row of 5 elements. And since it is vlen, each element is a 1d array of length 11.
That's what you get back in train_targets[0] - an array of 5 arrays, each shape (11,), with values taken from test (order F).
So I think there are 2 issues - what a 2d shape means, and what vlen allows.
My version of h5py is pre v2.3, so I only get string vlen. But I suspect your problem may be that vlen only works with 1d arrays, an extension, so to speak, of byte strings.
Does the 5 in shape=(9549, 5,) have anything to do with 5 in the test.shape? I don't think it does, at least not as numpy and h5py see it.
When I make a file following the string vlen example:
>>> f = h5py.File('foo.hdf5')
>>> dt = h5py.special_dtype(vlen=str)
>>> ds = f.create_dataset('VLDS', (100,100), dtype=dt)
and then do:
ds[0]='this one string'
and look at ds[0], I get an object array with 100 elements, each being this string. That is, I've set a whole row of ds.
ds[0,0]='another'
is the correct way to set just one element.
vlen is 'variable length', not 'variable shape'. While the https://www.hdfgroup.org/HDF5/doc/TechNotes/VLTypes.html documentation is not entirely clear on this, I think you can store 1d arrays with shape (11,) and (38,) with vlen, but not 2d ones.
Actually, train_targets output is reproduced with:
In [54]: test1=np.empty((5,),dtype=object)
In [55]: for i in range(5):
test1[i]=test.T.flatten()[i:i+11]
It's 11 values taken from the transpose (F order), but shifted for each sub array.

Putting multiple columns into callable sub arrays python

I have a set of data which is in columns, where the first column is the x values. How do i read this in?
If you want to store both, x and y values you can do
ydat = np.zeros((data.shape[1]-1,data.shape[0],2))
# write the x data
ydat[:,:,0] = data[:,0]
# write the y data
ydat[:,:,1] = data[:,1:].T
Edit:
If you want to store only the y-data in the sub arrays you can simply do
ydat = data[:,1:].T
Working example:
t = np.array([[ 0., 0., 1., 2.],
[ 1., 0., 1., 2.],
[ 2., 0., 1., 2.],
[ 3., 0., 1., 2.],
[ 4., 0., 1., 2.]])
a = t[:,1:].T
a
array([[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2.]])

Categories