apply a function to np.ndarray? - python

I have one numpy array, for instance a (a.shape = (2,20,50,50)). I would like to apply a function over its second axes.
My function is the difference between each elements only along the second axis, i.e.
res = a[:,i+1,:,:] - a[:,i,:,:] for i in range(20)
I have already tried it with lambda function, but the output is a list. I would like to have the result with the same shape as a. That means I want to have res.shape = (2,20,50,50).
I do appreciate that if someone guide me.
Thank you in advance.

You don't need to apply a function. Just subtract them directly.
res = a[:,1:,:,:]-a[:,0:-1,:,:]
Moreover, you won't get (2,20,50,50) ndarray but (2,19,50,50).

Related

How to get arrays that ouput result in brackets like [1][2][3] to [1 2 3]

The title kind of says it all. I have this (excerpt):
import numpy as np
import matplotlib.pyplot as plt
number_of_particles=1000
phi = np.arccos(1-2*np.random.uniform(0.0,1.,(number_of_particles,1)))
vc=2*pi
mux=-vc*np.sin(phi)
and I get out
[[-4.91272413]
[-5.30620302]
[-5.22400513]
[-5.5243784 ]
[-5.65050497]...]
which is correct, but I want it to be in the format
[-4.91272413 -5.30620302 -5.22400513 -5.5243784 -5.65050497....]
Feel like there should be a simple solution, but I couldn't find it.
Suppose your array is represented by the variable arr.
You can do,
l = ''
for i in arr:
l = l+i+' '
arr = [l]
Use this command:
new_mux = [i[0] for i in mux]
But I need it in an array, so then I add this
new_mux=np.array(new_mux)
and I get the desired output.
There's a method transpose in numpy's array object
mux.transpose()[0]
(I just noticed that this is a very old question, but since I have typed up this answer, and I believe it is simpler and more efficient than the existing ones, I'll post it...)
Notice that when you do
np.random.uniform(0.0,1.,(number_of_particles, 1))
you are creating a two-dimensional array with number_of_particles rows and one column. If you want a one-dimensional array throughout, you could do
np.random.uniform(0.0,1.,(number_of_particles,))
instead.
If you want to keep things 2d, but reshape mux for some reason, you can... well, reshape it:
mux_1d = mux.reshape(-1)
-1 here means "reshape it to one axis (because there’s just one number) and figure out automatically home many elements there should be along that axis (because the number is -1)."

Change array output to one without brackets

I changed a sparse dictionary into an array with (np.asarray). Then, I wrote a function that used that array to return the answer of a formula. However, I did that in a way the output includes the double brackets. Let's say the output is now:
[[7.58939191]]
but should be:
7.58939191
Can someone say how I can change this easily? Or do I have to share my function for this?
One way could be item method:
x.item(0)
See the documentation:
Copy an element of an array to a standard Python scalar and return it.
You can turn it into a numpy array, then compress the dimension:
import numpy as np
a = np.squeeze(np.asarray(a))
Then you can use a just like a number, for example:
b = a + 1

Creating a function in Python which runs over a range and returns a new value to an array each time

Basically, what I'm trying to create is a function which takes an array, in this case:
numpy.linspace(0, 0.2, 100)
and runs a lot of other code for each of the elements in the array and at the end creates a new array with one a number for each of the calculations for each element. A simple example would be that the function is doing a multiplication like this:
def func(x):
y = x * 10
return (y)
However, I want it to be able to take an array as an argument and return an array consisting of each y for each multiplication. The function above works for this, but the one I've tried creating for my code doesn't work with this method and only returns one value instead. Is there another way to make the function work as intended? Thanks for the help!
You could use this simple code:
def func(x):
y = []
for i in x:
y.append(i*10)
return y
Maybe take a look at np.vectorize:
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.vectorize.html
np.vectorize can for example be used as a decorator:
#np.vectorize
def func(value):
...
return return_value
The function to be vectorized (here func) has to be a function,
that takes a value as input and returns a value.
This function then gets vectorized over the whole array.
It is mentioned in the documentation, but it cant hurt to emphasize it here:
In general this function is only used for convenience not for performance,
it is basically equivalent to using a for-loop.
If you are able to build up your function from numpys ufuncs like (np.add, np.mean, etc.) this will likely be much faster.
Or you could write your own:
https://docs.scipy.org/doc/numpy-1.13.0/reference/ufuncs.html
You can do this with numpy already with your function. For example, the code below will do what you want:
x = numpy.linspace(0, 0.2, 100)
y = x*10
If you defined x as above and passed it to your function it would perform exactly as you want.

iterate over two numpy arrays return 1d array

I often have a function that returns a single value such as a maximum or integral. I then would like to iterate over another parameter. Here is a trivial example using a parabolic. I don't think its broadcasting since I only want the 1D array. In this case its maximums. A real world example is the maximum power point of a solar cell as a function of light intensity but the principle is the same as this example.
import numpy as np
x = np.linspace(-1,1) # sometimes this is read from file
parameters = np.array([1,12,3,5,6])
maximums = np.zeros_like(parameters)
for idx, parameter in enumerate(parameters):
y = -x**2 + parameter
maximums[idx] = np.max(y) # after I have the maximum I don't need the rest of the data.
print(maximums)
What is the best way to do this in Python/Numpy? I know one simplification is to make the function a def and then use np.vectorize but my understanding is it doesn't make the code any faster.
Extend one of those arrays to 2D and then let broadcasting do those outer additions in a vectorized way -
maximums = (-x**2 + parameters[:,None]).max(1).astype(parameters.dtype)
Alternatively, with the explicit use of the outer addition method -
np.add.outer(parameters, -x**2).max(1).astype(parameters.dtype)

Use of numpy fromfunction

im trying to use fromfunction to create a 5x5 matrix with gaussian values of mu=3 and sig=2, this is my attempt :
from random import gauss
import numpy as np
np.fromfunction(lambda i,j: gauss(3,2), (5, 5))
this is the result : 5.365244570434782
as i understand from the docs this should have worked, but i am getting a scalar instead of 5x5 matrix... why? and how to fix this?
The numpy.fromfunction docs are extremely misleading. Instead of calling your function repeatedly and building an array from the results, fromfunction actually only makes one call to the function you pass it. In that one call, it passes a number of index arrays to your function, instead of individual indices.
Stripping out the docstring, the implementation is as follows:
def fromfunction(function, shape, **kwargs):
dtype = kwargs.pop('dtype', float)
args = indices(shape, dtype=dtype)
return function(*args,**kwargs)
That means unless your function broadcasts, numpy.fromfunction doesn't do anything like what the docs say it does.
I know this is an old post, but for anyone stumbling upon this, the reason why it didn't work is, the expression inside lambda is not making use of the i, j variables
what you need could you achieved like this:
np.zeros((5, 5)) + gauss(3, 2)

Categories