Whether numpy array is immutable? - numpy

Arr = np.array([1,2,3,4,5])
Arr + 10 returns a new np array with 10 added to each cell
Original array isn't affected
Whereas Arr+=100 does the same but mutates the original array.
Does this mean numpy array is not immutable? Or is it shallow/deep copy?
I'm confused because operations like Arr[0]=100 mutate the original array?

numpy arrays are mutable.
__iadd__() modifies the array inplace.
try:
Arr += 10
__add__() will create a new array.

Related

How do you store and load a single element numpy array?

When I store and load a numpy array I have no issues unless the array only has a single element. When this happens, I am able to store and retrieve it, but the resulting type is not an array.
I was expecting that I would be able to retrieve the single element as I do multiple element arrays
import numpy as np
# set up the lists
listW = ["The Dog","The Cat"]
list = ["The Pig"]
# convert lists to arrays
arrayW = np.array(listW)
array = np.array(list)
# Displaying the original array
print('ArrayW:', arrayW)
print('Array:', array)
print('ArrayW[0]:', arrayW[0])
print('Array[0]:', array[0])
# storage files
fileW = "C:\\Test\\testW"
file = "C:\\Test\\test"
# Saving the original array
np.savetxt(fileW, arrayW, fmt='%s', delimiter=',')
np.savetxt(file, array, fmt='%s', delimiter=',')
# Loading the array from the saved files
testW = np.loadtxt(fileW, dtype=object, delimiter=',')
test = np.loadtxt(file, dtype=object, delimiter=',')
# print out results
print("testW:", testW)
print("test:", test)
print("testW[0]:", testW[0])
print("test[0]:", test[0])
When you run this, you get the following output:
ArrayW: ['The Dog' 'The Cat']
Array: ['The Pig']
ArrayW[0]: The Dog
Array[0]: The Pig
testW: ['The Dog' 'The Cat']
test: The Pig
testW[0]: The Dog
IndexError: too many indices for array: array is 0-dimensional, but 1 were indexed
The error is due to the fact that the read in value 'test' is not an array. This works if the stored array has more than 1 value.

Creating 2d array and filling first columns of each row in numpy

I have written the following code for creating a 2D array and filing the first element of each row. I am new to numpy. Is there a better way to do this?
y=np.zeros(N*T1).reshape(N,T1)
x = np.linspace(0,L,num = N)
for k in range(0,N):
y[k][0] = np.sin(PI*x[k]/L)
Simply do this:
y[:, 0] = np.sin(PI*x/L)

Taking a list of 2-d arrays and getting the non-zero values as ones in a single array with Numpy

I have a list of 2-d numpy arrays, and I wish to create one array consisting of the non-zero values (or-wise) of each array set to 1. For example
arr1 = np.array([[1,0],[0,0]])
arr2 = np.array([[0,10],[0,0]])
arr3 = np.array([[0,0],[0,8]])
arrs = [arr1, arr2, arr3]
And so my op would yield
op(arrs) = [[1, 1], [0, 1]]]
What is an efficient way to do this in numpy (for about 8 image arrays of 600 by 600)?
Took me a while to understand. Try just summing all the arrays keeping their dimensions and then replace non-zero values with 1 as follows-
def op(arrs):
return np.where(np.add.reduce(arrs) != 0, 1, 0)

Converting Fortran array to numpy array

I am in the process of converting a Fortran 90 code to python. The Fortran code includes multidimensional array like:
integer fvpair(3,12,2)
integer jpair(3,2)
real*8 aread(3,12)
I wonder if the following numpy array are correct equivalent, assuming zero initialization:
fvpair = np.array([[np.zeros(3)],[np.zeros(12)],[np.zeros(2)]])
jpair = np.array([[np.zeros(3)],[np.zeros(2)]])
aread = np.array([[np.zeros(3)],[np.zeros(12)]])
If you want to preserve the original Fortran array storage order (column-major), do not forget to pass the order='F' flag!
fvpair = np.zeros((3,12,2), dtype=int, order='F')
jpair = np.zeros((3,2), dtype=int, order='F')
aread = np.zeros((3,2), dtype=float64, order='F')

how to resize and subtract numpy arrays in c++

I have two numpy 3D-array in python with different height and width. I want to pass them to my C-Extension. How can I resize and subtract them in c++? Please see the comments in the code.
static PyObject *my_func(PyObject *self, PyObject *args)
{
Py_Initialize();
import_array();
PyObject *arr1;
PyObject *arr2;
if(!PyArg_ParseTuple(args, "OO", &arr1, &arr2))
{
return NULL;
}
//How can I do this?
//resize arr1 to [100, 100, 3]
//resize arr2 to [100, 100, 3]
//res = arr1 - arr2
//return res
}
Start by making the desired shape. It's easier to do this as a tuple than a list:
PyObject* shape = Py_BuildValue("iii",100,100,3);
Check this against NULL to ensure do error has occurred and handle if it has.
You can call the numpy resize function on both arrays to resize them. Unless you are certain that the data isn't shared then you need to call numpy.resize rather than the .resize method of the arrays. This involves importing the module and getting the resize attribute:
PyObject* np = PyImport_ImportModule("numpy");
PyObject* resize = PyObject_GetAttrString(np,"resize");
PyObject* resize_result = PyObject_CallFunctionObjArgs(resize,arr1, shape,NULL);
I've omitted all the error checking, which you should do after each stage.
Make sure you decrease the reference counts on the various PyObjects once you don't need them any more.
Use PyNumber_Subtract to do the subtraction (do it on the result from resize).
Addition: A shortcut for calling resize that should avoid most of the intermediates:
PyObject* np = PyImport_ImportModule("numpy");
// error check against null
PyObject* resize_result = PyObject_CallMethod(np,"resize","O(iii)",arr1,100,100,3);
(The "(iii)" creates the shape tuple rather than needing to do it separately.)
If you are certain that arr1 and arr2 are the only owners of the data then you can call the numpy .resize method either by the normal C API function calls or the specific numpy function PyArray_Resize.