How to create a matrix like below using Numpy - python

Matrix is like
[0, 1, 2]
[1, 2, 3]
[2, 3, 4]
For clarification, it's not just to create one such matrix but many other different matrices like this.
[0, 1, 2, 3]
[1, 2, 3, 4]
[2, 3, 4, 5]

You can use a sliding_window_view
from numpy.lib.stride_tricks import sliding_window_view as swv
cols = 4
rows = 3
out = swv(np.arange(cols+rows-1), cols).copy()
NB. because this is a view, you need .copy() to make it a mutable array, it's not necessary if a read-only object is sufficient (e.g., for display or indexing).
Output:
array([[0, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5]])
Output with cols = 3 ; rows = 5:
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 6]])
alternative: broadcasting:
cols = 4
rows = 3
out = np.arange(rows)[:,None] + np.arange(cols)
Output:
array([[0, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5]])

L = 3
np.array([
np.array(range(L)) + j
for j in range(L)
])
or a bit of optimization:
L = 3
a = np.array(range(L))
np.array([
a + j
for j in range(L)
])

You can easily create a matrix like that using broadcasting, for instance
>>> np.arange(3)[:, None] + np.arange(4)
array([[0, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5]])

Related

checking for elements in rows and columns of lists of lists without using pandas

If I have a list of lists
matrix = [[2, 3, 1, 2],[1, 2, 3, 2],[3, 3, 1, 2], [2, 2, 3, 3]]
how can I check with a for loop if for example element = 1 is present in each column
Using numpy:
np.any(a==1, 1).all()
>>> a = np.array([[2, 3, 1, 2],[1, 2, 3, 2],[3, 3, 1, 2], [2, 2, 3, 3]])
>>> np.any(a==1, 1).all()
False
>>> a = np.array([[2, 3, 1, 2],[1, 2, 3, 2],[3, 3, 1, 2], [2, 1, 3, 3]])
>>> np.any(a==1, 1).all()
True
Using all, in and a list comprehension:
matrix = [[2, 3, 1, 2], [1, 2, 3, 2], [3, 3, 1, 2], [2, 2, 3, 3]]
valid = all(1 in row for row in matrix)
Or, the verbose way:
matrix = [[2, 3, 1, 2], [1, 2, 3, 2], [3, 3, 1, 2], [2, 2, 3, 3]]
valid = True
for row in matrix:
if 1 not in row:
valid = False
break

How to expand the elements of a numpy matrix into sub matrices [duplicate]

This question already has answers here:
Quick way to upsample numpy array by nearest neighbor tiling [duplicate]
(3 answers)
Closed 3 years ago.
Let's say I have a numpy array:
x = np.array([[1, 2],
[3, 4]]
What is the easiest way to expand the elements into submatrices?
An intermediary result could look like this:
x = np.array([[[[1, 1],[1, 1]], [[2, 2],[2, 2]]],
[[[3, 3],[3, 3]], [[4, 4],[4, 4]]]]
And the desired result:
x = np.array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]]
You can use two repeats over the desired axes:
In [34]: np.repeat(np.repeat(x, 2, 1), 2, 0)
Out[34]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]])
Or as a faster approach (more suitable for larger arrays and repeat numbers) you can use as_strided:
In [43]: from numpy.lib.stride_tricks import as_strided
In [44]: x, y = arr.shape
In [45]: xs, ys = arr.strides
In [46]: result = as_strided(arr, (x, 2, y, 2), (xs, 0, ys, 0))
In [47]: result.reshape(x*2, y*2)
Out[47]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4]])
You can use numpy.repeat for the task. It has an axis argument.
>>> a = np.array([[1, 2], [3, 4]])
>>> a
array([[1, 2],
[3, 4]])
>>> np.repeat(a, 2)
array([1, 1, 2, 2, 3, 3, 4, 4])
>>> np.repeat(a, 2, axis=1)
array([[1, 1, 2, 2],
[3, 3, 4, 4]])
>>> np.repeat(np.repeat(a, 2, axis=1), 2, axis=0)
array([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])

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]])

delete last item in all rows and columns numpy.ndarray

I am trying to delete the last item in both the rows and columns in my numpy.ndarray (type = class numpy.ndarray). My array has 30 rows and 180 columns (i.e. 180 values per row). I have tried numpy.delete but this simply removes the whole row/column.
To illustrate what I want to achieve I created the following example in Python using and array and nested for loops:
a = np.array([[[1,2,3,4,5,6],[1,2,3,4],[1,2,3,4]],[[1,2,3,4,5,6],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4]],[[1,2,3,4],[1,2,3,4]]])
for list in a:
for sublist in list:
del sublist[-1]
Using
print(a)
Gives the following array:
[[[1, 2, 3, 4, 5, 6], [1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4, 5, 6], [1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] [[1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4]] [[1, 2, 3, 4], [1, 2, 3, 4]]
[[1, 2, 3, 4], [1, 2, 3, 4]] [[1, 2, 3, 4], [1, 2, 3, 4]]]
Using
print(list)
after the for loops gives:
[[1, 2, 3, 4, 5], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3, 4, 5], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
[[1, 2, 3], [1, 2, 3]]
Unfortunately using this on my array gives the following error:
TypeError: 'numpy.float64' object does not support item deletion
Thanks
Update:
I am extracting my information from a grid NetCDF file. I have changed the word list to l since list is a Python keyword. This didn't change it for me.
This provides a good example of my array:
c = np.arange(5400).reshape(30,180)
for l in c:
for i in l:
del i[-1]
When I run this code I get the following error:
Traceback (most recent call last): File "main.py", line 18, in <module>
del i[-1]
TypeError: 'numpy.int64' object does not support item deletion
del i[-1] is a list operation. np.array does not support that.
Count the occurrences of a specific value and remove them at the same time demonstrates the differences between lists and arrays when it comes to deletion.
Your example a is object dtype, containing lists
In [111]: a.shape
Out[111]: (11,)
In [112]: [len(i) for i in a]
Out[112]: [3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2]
In [113]: a[0]
Out[113]: [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4], [1, 2, 3, 4]]
a[0] is a 3 element list, with sublists of different length.
It's not clear what you want to delete. Delete elements from a, or elements from each element of a, or elements from the sublists of those elements.
Furthermore, if the real data is from NetCDF it might actually a multidimensional array. Or if object dtype, the elements might themselves be (2d) arrays.
In case, slicing is the right way to remove rows/columns from an array:
In [114]: a = np.arange(12).reshape(3,4)
In [115]: a
Out[115]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [116]: a[:-1, :-1]
Out[116]:
array([[0, 1, 2],
[4, 5, 6]])
The result is a view; it does not change a itself. a = a[:-1, :-1].copy() is the cleanest way to creates a reduced size array without leaving the any of the original around.

How to add ones to matrix?

I have an array:
X = [[2, 2, 2],
[3, 3, 3],
[4, 4, 4]]
I need to add extra column in numpy array and fill it with ones using hstack and reshape. Like that:
X = [[2, 2, 2, 1],
[3, 3, 3, 1],
[4, 4, 4, 1]]
What I do:
X = np.hstack(X, np.ones(X.reshape(X, (2,3))))
And a get an error:
TypeError: only length-1 arrays can be converted to Python scalars
What's a problem? What I've done wrong?
Here's a couple ways with numpy.append, numpy.hstack or numpy.column_stack:
# numpy is imported as np
>>> x
array([[2, 2, 2],
[3, 3, 3],
[4, 4, 4]])
>>> np.append(x, np.ones([x.shape[0], 1], dtype=np.int32), axis=1)
array([[2, 2, 2, 1],
[3, 3, 3, 1],
[4, 4, 4, 1]])
>>> np.hstack([x, np.ones([x.shape[0], 1], dtype=np.int32)])
array([[2, 2, 2, 1],
[3, 3, 3, 1],
[4, 4, 4, 1]])
>>> np.column_stack([x, np.ones([x.shape[0], 1], dtype=np.int32)])
array([[2, 2, 2, 1],
[3, 3, 3, 1],
[4, 4, 4, 1]])
You can use numpy.insert():
>>> X
array([[2, 2, 2],
[3, 3, 3],
[4, 4, 4]])
Ones at the begining of matrix:
>>> X=np.insert(X,0,1.0,axis=1)
>>> X
array([[1, 2, 2, 2],
[1, 3, 3, 3],
[1, 4, 4, 4]])
Ones at the end of matrix
>>> X=np.insert(X,3,1.0,axis=1)
>>> X
array([[2, 2, 2, 1],
[3, 3, 3, 1],
[4, 4, 4, 1]])

Categories