What is this object called? - python

I have a matrix of the following form:
a=[[1 2 3 4]
[2 5 7 6]
[5 4 2 1]]
(for example).
Firstly, what are each of the elements called? ie. what type of object is [1 3 4] (a list without the commas). Secondly, how would I go about turning each of these 'things' into a list, so that the matrix reads:
b=[[1, 2, 3, 4]
[2, 5, 7, 6]
[5, 4, 2, 1]]
?
I started with a list of lists and then used insert to replace each list with a matrix of that list and it turned it into a. However, it was necessary for me to do so as I needed to keep lists in order and multiply by a matrix.
Thank you in advance for any help!

The object is a numpy.matrix and is converted to a list simply as:
as_list = a.tolist()

As thefourtheye says, it's probably a Numpy ndarray.

Following the insight from earlier answers, this quick demo might answer your question
>>>import numpy as np
>>> a = np.array([[1, 2, 3, 4], [2, 5, 7, 6], [5, 4, 2, 1]])
>>> a
array([[1, 2, 3, 4],
[2, 5, 7, 6],
[5, 4, 2, 1]])
>>> print(a)
[[1 2 3 4]
[2 5 7 6]
[5 4 2 1]]
>>> b = list(a)
>>> print(b)
[array([1, 2, 3, 4]), array([2, 5, 7, 6]), array([5, 4, 2, 1])]
>>> b = [list(e) for e in a]
>>> b
[[1, 2, 3, 4], [2, 5, 7, 6], [5, 4, 2, 1]]
Thus '[1 3 4]' is called a numpy array.
-- revised for matrix --
>>> a = np.matrix([[1, 2, 3, 4], [2, 5, 7, 6], [5, 4, 2, 1]])
>>> a
matrix([[1, 2, 3, 4],
[2, 5, 7, 6],
[5, 4, 2, 1]])
>>>
>>> print(a)
[[1 2 3 4]
[2 5 7 6]
[5 4 2 1]]
>>> a.tolist()
[[1, 2, 3, 4], [2, 5, 7, 6], [5, 4, 2, 1]]

Related

Multiplication product of elements in each row of a 2-D matrix using python

a = [[1 2 3],
[4 2 1],
[1 3 4]]
the answer should be [6 8 12]
I have tried a lot but I'm not able to solve it please help.
import math
a = [[1, 2, 3], [4, 2, 1], [1, 3, 4]]
print([math.prod(r) for r in a])
You could use numpy.prod
import numpy as np
a = [[1, 2, 3], [4, 2, 1],[1, 3, 4]]
print(np.prod(a, 1))
[6 8 12]
without using math or numpy:
def product(myList) :
result = 1
for i in myList:
result = result * i
return result
a = [[1, 2, 3], [4, 2, 1], [1, 3, 4]]
b = [product(l) for l in a]
print(b) # [6, 8, 12]
a= [1, 2, 3, 4, 2, 1, 1, 3, 4]
print([a[idx]*a[idx-1]*a[idx-2] for idx, _ in enumerate(a) if (idx+1)%3==0 ])

Changing shape of a numpy array in a way that keeps the indices/positions of elements the same

Suppose I have the following numpy array
[[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]
[7 8 9]]]
I want to be able to resize this array (making it smaller or larger along an axis) but have existing elements have the same indices as they did before the resize. So, if I decreased the size of axis 2 by one element, it would look like this:
[[[1 2]
[4 5]
[7 8]]
[[1 2]
[4 5]
[7 8]]
[[1 2]
[4 5]
[7 8]]]
And if I increased the size of axis 1, it would look like this:
[[[1 2 3]
[4 5 6]
[7 8 9]
[0 0 0]]
[[1 2 3]
[4 5 6]
[7 8 9]
[0 0 0]]
[[1 2 3]
[4 5 6]
[7 8 9]
[0 0 0]]]
How would I do this, short of implementing all the loops and everything myself?
For reference, if I use the Numpy resize() function, and do np.resize(my_array, (3, 3, 2)) to decrease the size of axis 2 from 3 to 2, Numpy simply changes the sizes of the dimensions and doesn't reorganize the array data itself, meaning that indices of elements are not preserved:
[[[1 2]
[3 4]
[5 6]]
[[7 8]
[9 1]
[2 3]]
[[4 5]
[6 7]
[8 9]]]
You can try defining a class that inherits from the np.ndarray class, defining an extra bound function that does the "resizing":
import numpy as np
class Array(np.ndarray):
def __new__(cls, a, dtype=None, order=None):
obj = np.asarray(a, dtype, order).view(cls)
return obj
def __array_wrap__(self, out_arr, context=None):
return np.ndarray.__array_wrap__(self, out_arr, context)
def resizing(self, cols):
return self[..., :cols]
arr = np.tile(np.arange(1, 10), 3).reshape(3, 3, 3)
arr = Array(arr)
Now we can do:
print(arr.resizing(1))
Output:
[[[1]
[4]
[7]]
[[1]
[4]
[7]]
[[1]
[4]
[7]]]
print(arr.resizing(2))
Output:
[[[1 2]
[4 5]
[7 8]]
[[1 2]
[4 5]
[7 8]]
[[1 2]
[4 5]
[7 8]]]
You don't want resize or reshape
Make a sample array:
In [29]: arr = np.arange(1,10).reshape(1,3,3)
In [30]: arr
Out[30]:
array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]])
To get your (3,3,3) array use repeat. To keep the answer short, I'll stick with the (1,3,3):
In [31]: arr.repeat(3,0)
Out[31]:
array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]])
Slicing can "cut off" a column
In [33]: arr[:,:,:2]
Out[33]:
array([[[1, 2],
[4, 5],
[7, 8]]])
Adding on a row, use concatenate:
In [36]: np.concatenate((arr, np.zeros((1,1,3),int)), axis=1)
Out[36]:
array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0, 0, 0]]])
Keep in mind that numpy stores an array as shape and a 1d data-buffer.
In [40]: arr.ravel()
Out[40]: array([1, 2, 3, 4, 5, 6, 7, 8, 9])
arr is a reshape from arange. Reshape preserves that 1d source. So it isn't suitable for the kinds of changes you want. resize works that 1d source also, though it can add on, or subtract from it. Think in terms of making a new array with selected values from the original, rather than changing the array.
I would use either np.pad or np.zeros.
using np.pad:
Build example array:
>>> import numpy as np
>>>
>>> A = np.resize(np.r_[1:10],(3,3,3))
>>> A
array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]])
Define the function
>>> def recut_pad(A,shp):
... return np.pad(A[tuple(map(slice,shp))],[(0,max(0,sn-so)) for sn,so in zip(shp,A.shape)])
Try it out:
>>> recut_pad(A,(2,4,5))
array([[[1, 2, 3, 0, 0],
[4, 5, 6, 0, 0],
[7, 8, 9, 0, 0],
[0, 0, 0, 0, 0]],
[[1, 2, 3, 0, 0],
[4, 5, 6, 0, 0],
[7, 8, 9, 0, 0],
[0, 0, 0, 0, 0]]])
>>> recut_pad(A,(4,2,2))
array([[[1, 2],
[4, 5]],
[[1, 2],
[4, 5]],
[[1, 2],
[4, 5]],
[[0, 0],
[0, 0]]])
Using np.zeros and slicing:
Define the function:
>>> def recut_zeros(A,shp):
... out = np.zeros(shp,A.dtype)
... out[tuple(map(slice,A.shape))] = A[tuple(map(slice,shp))]
... return out
Verify:
>>> np.all(recut_pad(A,(1,5,4))==recut_zeros(A,(1,5,4)))
True
>>> np.all(recut_pad(A,(7,2,3))==recut_zeros(A,(7,2,3)))
True

Add elements of a list to all elements in certain columns

Here my "problem":
Given a numpy array as
array([[4, 3, 5, 1],
[2, 3, 3, 4],
[4, 2, 2, 7]])
what I would like to do now is use a list of values
values = [3, 2]
and add them to all elements of certain columns, e.g. columns 2 and 3 leading to
new_array([[4,6,7,1],
[2,6,5,4],
[4,5,4,7]])
How can that be done?
a = np.array([[4, 3, 5, 1],
[2, 3, 3, 4],
[4, 2, 2, 7]])
values = [3, 2]
a[:,(1,2)] += values
print(a)
Prints:
[[4 6 7 1]
[2 6 5 4]
[4 5 4 7]]

Numba list argument for array indexing

I'm looking to leverage numba to iterate over a large 2d array, where for iteration a subset of the array will be selected by [x, y] location (passed as an argument). I'm having trouble with structuring this the right way to play nice with numba, specifically when passing a list of lists as an argument into the method. Any pointers?
x_y_list = [[1, 2], [3, 4], [5, 6]]
array = ([[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6]])
#jit
def arrIndexing(array, x_y_list):
for index in x_y_list:
subset = array[index[0]-1:index[0]+1, index[1]-1:index[1]+1]
# do some other stuff
Something like this?
Should do well with Numba but I haven’t tested (did this on my phone which doesn’t support Numba)
import numpy as np
def xy():
x_y_list = np.array([[1, 2], [2, 4], [0, 5]])
array = np.array([[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6]])
for i,j in x_y_list:
print(array[np.ix_((i-1, i), (j-1, j))])
>>> xy()
[[2 3]
[2 3]]
[[4 5]
[4 5]]
[[5 6]
[5 6]]

list as columns in python

I have a list for example:
x = [1,2,3,4,5]
and I want to convert it into a matrix that looks like so:
mat = [ 1 1 1
2 2 2
3 3 3
4 4 4
5 5 5 ]
so each column in the matrix is the list.
is there an easy way doing so with numpy or just regular python?
thank you
Maybe you need to repeat i.e
n = 3 # No of repetition
np.repeat(np.array(x),n).reshape(-1,n)
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4],
[5, 5, 5]])
without any modules
a = [1, 2, 3, 4, 5]
n = 3
b = [[x] * n for x in a]
print(b)
Let's use np.tile:
import numpy as np
arr = np.array(x)
np.tile(arr,3).reshape(5,3, order='F')
Output:
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4],
[5, 5, 5]])
Another array option:
In [248]: np.stack([a]*3,axis=1)
Out[248]:
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4],
[5, 5, 5]])
You need to be careful with list replication:
In [250]: b=[a]*3
In [251]: b[0][0]=30
In [252]: b
Out[252]: [[30, 2, 3, 4, 5], [30, 2, 3, 4, 5], [30, 2, 3, 4, 5]]
# a is also changed
It replicates the pointer, not the values. The array stack makes a copy.
np.array will join those lists along a new first axis. stack does something similar (but using np.concatenate), and allows us to join them on a new 2nd axis.
In [255]: np.array(b)
Out[255]:
array([[30, 2, 3, 4, 5],
[30, 2, 3, 4, 5],
[30, 2, 3, 4, 5]])

Categories