Numpy: equivalent of numpy.roll but only for data visualisation - python

Is there a way to perform a roll on an array, but instead of having a copy of the data having just a different visualisation of it?
An example might clarify: given b a rolled version of a...
>>> a = np.random.randint(0, 10, (3, 3))
>>> a
array([[6, 7, 4],
[5, 4, 8],
[1, 3, 4]])
>>> b = np.roll(a, 1, axis=0)
>>> b
array([[1, 3, 4],
[6, 7, 4],
[5, 4, 8]])
...if I perform an assignment on array b...
>>> b[2,2] = 99
>>> b
array([[ 1, 3, 4],
[ 6, 7, 4],
[ 5, 4, 99]])
...the content of a won't change...
>>> a
array([[6, 7, 4],
[5, 4, 8],
[1, 3, 4]])
...contrarily, I would like to have:
>>> a
array([[6, 7, 4],
[5, 4, 99], # observe as `8` has been changed here too!
[1, 3, 4]])
Thanks in advance for your time and expertise!

This is not possible, sorry. The rolled array cannot be described by a different set of strides, which would be necessary for a NumPy view to work.

Related

Creating shifted Hankel matrix

Say I have some time-series data in the form of a simple array.
X1 = np.array[(1, 2, 3, 4]
The Hankel matrix can be obtained by using scipy.linalg.hankel, which would look something like this:
hankel(X1)
array([[1, 2, 3, 4],
[2, 3, 4, 0],
[3, 4, 0, 0],
[4, 0, 0, 0]])
Now assume I had a larger array in the form of
X2 = np.array([1, 2, 3, 4, 5, 6, 7])
What I want to do is fill in the zeros in this matrix with the numbers that are next in the index (specific to each row). Taking the same Hankel matrix earlier by using the first four values in the array X2, I'd like to see the following output:
hankel(X2[:4])
array([[1, 2, 3, 4],
[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7]])
How would I do this? I'd ideally like to use this for larger data.
Appreciate any tips or pointers given. Thanks!
If you have a matrix with the appropriate index values into your dataset, you can use integer array indexing directly into your dataset.
To create the index matrix, you can simply use the upper-left quadrant of a double-sized Hankel array. There are likely simpler ways to create the index matrix, but this does the trick.
>>> X = np.array([9, 8, 7, 6, 5, 4, 3])
>>> N = 4 # the size of the "window"
>>> indices = scipy.linalg.hankel(np.arange(N*2))[:N, :N]
>>> indices
array([[0, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5],
[3, 4, 5, 6]])
>>> X[indices]
array([[9, 8, 7, 6],
[8, 7, 6, 5],
[7, 6, 5, 4],
[6, 5, 4, 3]])

Numpy Multidimensional Array

I'm new to numpy, I don't understand how the following works:
np.array([range(i, i + 3) for i in [2, 4, 6]])
and the output is:
array([[2, 3, 4],[4, 5, 6],[6, 7, 8]])
Do you understand list comprehensions? range?
In [12]: [range(i, i + 3) for i in [2, 4, 6]]
Out[12]: [range(2, 5), range(4, 7), range(6, 9)]
np.array converts the range objects to lists, and then builds the array.
In [13]: [list(range(i, i + 3)) for i in [2, 4, 6]]
Out[13]: [[2, 3, 4], [4, 5, 6], [6, 7, 8]]
In [14]: np.array([list(range(i, i + 3)) for i in [2, 4, 6]])
Out[14]:
array([[2, 3, 4],
[4, 5, 6],
[6, 7, 8]])
So basically it's just a variation on the textbook example of making an array from a list of lists:
In [15]: np.array([[1,2,3],[10,11,12]])
Out[15]:
array([[ 1, 2, 3],
[10, 11, 12]])

Insert 1D NumPy array as column in existing 2D array

I have a 2D NumPy array:
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> a
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
and a 1D array:
>>> b = np.arange(3)
>>> b
array([0, 1, 2])
Is there an elegant way to insert b into a as a new first column?
So that:
>>> a
array([[0, 1, 2, 3],
[1, 4, 5, 6],
[2, 7, 8, 9]])
You could use column_stack()
In [256]: np.column_stack((b, a))
Out[256]:
array([[0, 1, 2, 3],
[1, 4, 5, 6],
[2, 7, 8, 9]])

Concatenate 3 unidimensional arrays together in numpy

I'm leaving MatLab for numpy and in general it's going ok, but I'm having a nightmare finding a nice pythonic way to do what would have done this in MatLab:
A=[1.0;2.0;3.0;4.0] %Column vector
B=[5.0;6.0;7.0;8.0] %Another one
C=[A,B,B] %4 x 3 matrix
In Python, setting up A like so:
A=np.array([1,2,3,4])
B=np.array([5,6,7,8])
And concatenating like so:
C=np.concatenate((A,B,B),axis=1)
Stacks them one on top of the other, and _C, hstack etc fail as well. I'm guessing I need a nice pyythonic way of turning a (4,) numpy array into a (4,1) array. In my code these vectors are much bigger than this and are created dynamically so I can't just type:
A=np.array([[1],[2],[3],[4]])
Thanks in advance for any help!
I would use dstack
>>> A=np.array([1,2,3,4])
>>> B=np.array([5,6,7,8])
>>> np.dstack((A, B, B))
array([[[1, 5, 5],
[2, 6, 6],
[3, 7, 7],
[4, 8, 8]]])
You can use np.c_[A,B,B], which gives
array([[1, 5, 5],
[2, 6, 6],
[3, 7, 7],
[4, 8, 8]])
>>> C=np.array([A,B,B])
>>> C
array([[1, 2, 3, 4],
[5, 6, 7, 8],
[5, 6, 7, 8]])
or:
>>> C=np.array([A,B,B]).swapaxes(1,0)
>>> C
array([[1, 5, 5],
[2, 6, 6],
[3, 7, 7],
[4, 8, 8]])

NumPy array indexing

I want to extract the second and the 3rd to the fifth columns of the NumPy array, how would I go about it?
A = array([[0, 1, 2, 3, 4, 5, 6], [4, 5, 6, 7, 4, 5, 6]])
A[:, [1, 4:6]]
This obviously doesn't work.
Assuming I've understood you -- it's usually a good idea to explicitly specify the output you want, because it's not obvious -- you could use numpy.r_:
In [27]: A
Out[27]:
array([[0, 1, 2, 3, 4, 5, 6],
[4, 5, 6, 7, 4, 5, 6]])
In [28]: A[:, [1,3,4,5]]
Out[28]:
array([[1, 3, 4, 5],
[5, 7, 4, 5]])
In [29]: A[:, r_[1, 3:6]]
Out[29]:
array([[1, 3, 4, 5],
[5, 7, 4, 5]])
In [37]: A[1:, r_[1, 3:6]]
Out[37]: array([[5, 7, 4, 5]])
which you can then flatten or reshape as you like. r_ is basically a convenience function to generate the right indices, e.g.
In [30]: r_[1, 3:6]
Out[30]: array([1, 3, 4, 5])
Perhaps you are looking for this?
In [10]: A[1:, [1]+range(3,6)]
Out[10]: array([[5, 7, 4, 5]])
Note this gives you the second, fourth, fifth and six columns of all rows but the first.
The second element is A[:,1]. Elements 3-5 (I'm assuming you want inclusive) are A[:,2:5]. You won't be able to extract them with a single call. To get them as an array, you could do
import numpy as np
A = np.array([[0, 1, 2, 3, 4, 5, 6], [4, 5, 6, 7, 4, 5, 6]])
my_cols = np.hstack((A[:,1][...,np.newaxis], A[:,2:5]))
The np.newaxis stuff is just to make A[:,1] a 2D array, consistent with A[:,2:5].
Hope this helps.

Categories

Resources