Resizing an array to another shape in Python - python

I have the following array:
a = np.random.rand(5,2)
a
array([[0.98736372, 0.07639041],
[0.45342928, 0.4932295 ],
[0.75789786, 0.48546238],
[0.85854235, 0.74868237],
[0.13534155, 0.79317482]])
and I want to resize it so that it is divided into 2 batches with three elements (adding zeros as required):
array([[[0.98736372, 0.07639041],
[0.45342928, 0.4932295 ],
[0.75789786, 0.48546238]],
[[0.85854235, 0.74868237],
[0.13534155, 0.79317482],
[0, 0]]])
I have tried this, but it returns None:
a = a.copy()
a.resize((2,3,2), refcheck = False)
I believe .reshape would not provide the solution, as it is not able to fill in with 0's to comply with the desired dimensions for the array.

Using numpy.resize, you have to use like this:
import numpy as np
a = np.random.rand(5,2)
b = np.resize(a, (2,3,2))
otherwise you can use the object method to get the same result, like this:
import numpy as np
a = np.random.rand(5,2)
a.np.resize(2,3,2)
b = a.copy()
note the first one return ndarray and the last one returns None because It changes the object itself. For more info, look the numpy.resize doc

Related

Issue with vectorization in python

I have an application where I need to merge two solutions obtained from the scipy.integrate.solve_ivp in python. The actual application is a bit more complicated, but the following example shows the idea:
from scipy.integrate import solve_ivp import numpy as np
def lotkavolterra(t, z, a, b, c, d):
x, y = z
return [a*x - b*x*y, -c*y + d*x*y]
sol_1 = solve_ivp(lotkavolterra, [0, 10], [10, 5], args=(1.5, 1, 3, 1), dense_output=True).sol
sol_2 = solve_ivp(lotkavolterra, [10, 15], [10, 5], args=(1.5, 1, 3, 1), dense_output=True).sol
def sol_comb(t):
if t <= 10:
return sol_1(t)
else:
return sol_2(t)
I want to be able to use the merged or combined solution sol_comb on numpy arrays. Hence I tried to define a vectorized solution as follows:
sol_comb_vect = np.vectorize(sol_comb)
The following code, where I only call the functions on scalars, works fine:
print("sol_1 for t = 2",sol_1(2))
print("sol_2 for t = 11",sol_2(11))
print("sol_comb for t = 11",sol_comb(11))
print("sol_comb_vect for t = 11",sol_comb_vect(11))
The individual solutions sol_1 and sol_2 are apparently vectorized, since the following works fine:
print("sol_1 for t = [2,3]",sol_1(np.array([2])))
print("sol_2 for t = [11,13]",sol_2(np.array([11,13])))
However, if I call the non-vectorized function sol_comb on an array, as in the following example, I get the expected ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all():
print("sol_comb for t = [11,13]",sol_comb(np.array([11,13])))
I was expecting the vectorized version sol_comb_vect to work. However, in the following, I get the error ValueError: setting an array element with a sequence.
print("sol_comb_vect for t = [11,13]",sol_comb_vect(np.array([11,13])))
Any ideas how to fix this?
I would also be happy to merge the two OdeSolution instances in a cleaner way. In principle I think this should be possible, by using the time values and interpolants for sol_1 and sol_2, respectively.
I think you need to specify the signature for your output when you vectorize your function since by default the pyfunc you pass to np.vectorize() is assumed to take scalars as input and output see doc. And I assume that your ValueError is caused by that. So try this:
sol_comb_vect = np.vectorize(sol_comb, signature='()->(n)')
sol_comb_vect(np.array([2, 11, 13]))
output:
array([[0.60031288, 0.09618044],
[0.21298705, 1.36999868],
[2.58274789, 0.01857732]])
I don't know if this is the expected output tho. I hope this answers your question.

return a 2d array without brackets

I'm trying to create a function that returns a 2d array without the brackets on the sides of the array, And I can't use print since I'm using this function for a discord bot and want to return the array instead of printing it.
Here's some of my code:
import numpy as np
example_array = np.array([["⚪", "⚪", "⚪"], ["⚪", "⚪", "⚪"], ["⚪", "⚪", "⚪"]])
def get_array():
for row in example_array:
return "".join(map(str,row))
X = print_array()
Here's the output if I print/send X:
⚪⚪⚪
How can I use a function to return the full array?
I think what you want to do is something like this
"".join(["".join(i) for i in example_array])
would give us
'⚪⚪⚪⚪⚪⚪⚪⚪⚪'

How to create numpy arrays automatically?

I wanted to create arrays by for loop to assign automatically array names.
But using a for loop, it didn't work and creating a dictionary with numpy.array() in it, does not work, too. Currently, I have no more ideas...
I am not really safe in handling with python.
import numpy as np
for file_name in folder:
file_name = np.array()
file_name.extend((blabla, blabla1))
I expected to get arrays with automatically assigned names, like file_name1, file_name2, ...
But I got the advice, "redeclared file_name defined above without usage" and the output was at line file_name = np.array()
TypeError: array() missing required argument 'object' (pos 1) ...
You can do it with globals() if you really want to use the strings as named variables.
globals()[filename] = np.array()
Example:
>>> globals()['test'] = 1
>>> test
1
Of course this populates the global namespace. Otherwise, you can use locals().
As #Mark Meyer said in comment, you should use dictionary (dict in Python) by setting file_name as key.
As per your error, when you create a numpy array, you should provide an iterable (ex. a list).
For example:
>>> folder = ['file1', 'file2']
>>> blabla = 0
>>> blabla1 = 1
>>> {f: np.array((blabla, blabla1)) for f in folder}
{'file1': array([0, 1]), 'file2': array([0, 1])}

Re-arranging numpy array in place

I am trying to modify a numpy array "in-place". I am interested in re-arranging the array in-place (instead of return:ing a re-arranged version of the array).
Here is an example code:
from numpy import *
def modar(arr):
arr=arr[[1,0]] # comment & uncomment this line to get different behaviour
arr[:,:]=0
print "greetings inside modar:"
print arr
def test2():
arr=array([[4,5,6],[1,2,3]])
print "array before modding"
print arr
print
modar(arr)
print
print "array now"
print arr
test2()
The assignment ar=arr[[1,0]] breaks the correspondence of "arr" to the original array passed to the function "modar". You can confirm this by commenting/uncommenting that line.. this happens, of course, as a new array has to be created.
How can I tell python that the new array still corresponds to "arr"?
Simply, how can I make "modar" to rearrange the array "in-place"?
Ok.. I modified that code and replaced "modarr" by:
def modar(arr):
# arr=arr[[1,0]] # comment & uncomment this line to get different behaviour
# arr[:,:]=0
arr2=arr[[1,0]]
arr=arr2
print "greetings inside modar:"
print arr
The routine "test2" still gets an unmodified array from "modar".
"For all cases of index arrays, what is returned is a copy of the
original data, not a view as one gets for slices."
http://docs.scipy.org/doc/numpy/user/basics.indexing.html
In this case you could do:
arr2 = arr[[1, 0]]
arr[...] = arr2[...]
where the temporary array arr2 is used to store the fancy indexing result. The last line copies the data from arr2 to the original array, keeping the reference.
Note: be sure in your operations that arr2 has the same shape of arr in order to avoid strange results...
Here is a solution with additional playing around. Basically the same as Saullo's.
from numpy import *
def modar1(arr):
# arr=arr[[1,0]] # (a)
arr[:,:]=arr[[1,0]][:,:] # (b)
print "greetings inside modar:"
print arr
# (a) arr is now referring to a new array .. python does not know if it
# has the same type / size as the original parameter array
# and therefore "arr" does not point to the original parameter array anymore. DOES NOT WORK.
#
# (b) explicit copy of each element. WORKS.
def modar2(arr):
arr2=arr.copy()
arr2=arr2[[1,0]]
# arr=arr2 # (a)
arr[:,:]=arr2[:,:] # (b)
print "greetings inside modar:"
print arr
# (a) same problem as in modar1
# .. it seems that *any* reference "arr=.." will point "arr" to something else as than original parameter array
# and "in-place" modification does not work. DOES NOT WORK
#
# (b) does an explicit copying of each array element. WORKS
#
def modar3(arr):
arr2=arr.copy()
arr2=arr2[[1,0]]
for i in range(arr.shape[0]):
arr[i]=arr2[i]
print "greetings inside modar:"
print arr
# this works, as there is no reference "arr=", i.e. to the whole array
def test2():
#
# the goal:
# give an array "arr" to a routine "modar"
# After calling that routine, "arr" should appear re-arranged
#
arr=array([[4,5,6],[1,2,3]])
print "array before modding"
print arr
print
modar1(arr) # OK
# modar2(arr) # OK
# modar3(arr) # OK
print
print "array now"
print arr
test2()

Python 2.6 numpy interaction array objects error

I have a multi-dimensional array of objects. I want to interate over the objects using the nditer iterator.
Here is a code example:
import numpy as np
class Test:
def __init__(self,a):
self.a = a
def get_a(self):
return self.a
b = np.empty((2,3),dtype = object)
t_00 = Test(0)
t_01 = Test(1)
t_11 = Test (11)
b[0,0] = t_00
b[0,1] = t_01
b[1,1] = t_11
for item in np.nditer(b,flags = ["refs_ok"]):
if item:
print item.get_a()
I would expect the "item" to contain the object reference that I can use to access data.
However I am getting the following error:AttributeError: 'numpy.ndarray' object has no attribute 'get_a'
My question is how can I go thru the array to access the object in the array?
The array.flat method of iteration will work, and can confirm that this works as you'd expect
for item in b.flat:
if item:
print item.get_a()
Iterating over an array with nditer gives you views of the original array's cells as 0-dimensional arrays. For non-object arrays, this is almost equivalent to producing scalars, since 0-dimensional arrays usually behave like scalars, but that doesn't work for object arrays.
If you were determined to go through nditer for this, you could extract the elements from the 0-dimensional views with the item() method:
for element in np.nditer(b,flags = ["refs_ok"]):
element = element.item()
if element:
print(element.get_a())

Categories

Resources