I'm trying to interchange the rows of np.array A using the following array:
A = np.array([[0,-3,-6,4,9],
[-1,-2,-1,3,1],
[-2,-3,0,3,-1],
[1,4,5,-9,-7]])
When I use the following code:
A = np.array([A[3],A[0],A[1],A[2]])
my array becomes
array([[ 1, 4, 5, -9, -7],
[ 0, -3, -6, 4, 9],
[-1, -2, -1, 3, 1],
[-2, -3, 0, 3, -1]])
like I hoped, wished and dreamed. When I try a broader slice, though (as I would need for larger matrices), it doesn't work quite as well:
A = np.array([A[3], A[0:3]])
A
array([array([-2, -3, 0, 3, -1]),
array([[ 1, 4, 5, -9, -7],
[ 0, -3, -6, 4, 9],
[-1, -2, -1, 3, 1]])], dtype=object)
Why is this happening/how can I correctly perform this slice?
The first expression can be written much more simply as
A = A[[3, 0, 1, 2], :])
The second can therefore be written as
A = A[[3, *range(3)], :]
This is more general than using roll, since you can move an arbitrary row with something like
A = A[[1, *range(1), *range(2, 4)], :]
You could use vstack:
In [5]: np.vstack([A[3], A[0:3]])
Out[5]:
array([[ 1, 4, 5, -9, -7],
[ 0, -3, -6, 4, 9],
[-1, -2, -1, 3, 1],
[-2, -3, 0, 3, -1]])
np.roll as commented is probably the best choice. You could also use np.r_:
A[np.r_[3,0:3]]
Out:
array([[ 1, 4, 5, -9, -7],
[ 0, -3, -6, 4, 9],
[-1, -2, -1, 3, 1],
[-2, -3, 0, 3, -1]])
Related
i want to generate a diagonal matrix with size such as nxn
This is a toeplitz matrix, you can use SciPy's linalg.toeplitz to construct such a pattern. You can look at its implementation code here which uses from np.lib.stride_tricks.as_strided under the hood.
>>> toeplitz(-np.arange(3), np.arange(3))
array([[ 0, 1, 2],
[-1, 0, 1],
[-2, -1, 0]])
>>> toeplitz(-np.arange(6), np.arange(6))
array([[ 0, 1, 2, 3, 4, 5],
[-1, 0, 1, 2, 3, 4],
[-2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2],
[-4, -3, -2, -1, 0, 1],
[-5, -4, -3, -2, -1, 0]])
It's quite easy to write as a custom function:
def diagonal(N):
a = np.arange(N)
return a-a[:,None]
diagonal(3)
array([[ 0, 1, 2],
[-1, 0, 1],
[-2, -1, 0]])
diagonal(6)
array([[ 0, 1, 2, 3, 4, 5],
[-1, 0, 1, 2, 3, 4],
[-2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2],
[-4, -3, -2, -1, 0, 1],
[-5, -4, -3, -2, -1, 0]])
I am using the matrix for the multiple sequence alignment and this is my score matrix which I got by running the alignment algorithm.
My matrix:
[
[0, 24, -5, 3, -3, -5],
[0, -4, 8, 1, 1],
[0, 13, 1, 2],
[0, -2, 5],
[0, 4],
[0]
]
Matrix I want to build:
[
[0, 24, -5, 3, -3, -5],
[24, 0, -4, 8, 1, 1],
[-5, -4, 0, 13, 1, 2],
[3, 8, 13, 0, -2, 5],
[-3, 1, 1, 2, 0, 4],
[-5, 1, 2, 5, 4, 0]
]
I am trying to create a symmetric matrix from the output I got in python without using NumPy and additional library. I have tried to implement using NumPy but I want to implement without using NumPy.
Try the following:
upper = [[0, 24, -5, 3, -3, -5], [0, -4, 8, 1, 1], [0, 13, 1, 2], [0, -2, 5], [0, 4], [0]]
n = len(upper) # 6: num of rows and cols (assuming square)
output = []
for i in range(n): # iterate over rows
row = [(upper[i][j - i] if j >= i else output[j][i]) for j in range(n)]
output.append(row)
print(output)
# [[0, 24, -5, 3, -3, -5], [24, 0, -4, 8, 1, 1], [-5, -4, 0, 13, 1, 2], [3, 8, 13, 0, -2, 5], [-3, 1, 1, -2, 0, 4], [-5, 1, 2, 5, 4, 0]]
im trying to reshape the following numpy array.
from this:
array([[[ 1, 2, 3],
[ 2, 3, 4],
[ 3, 4, 5]],
[[-1, -2, -3],
[-2, -3, -4],
[-3, -4, -5]]], dtype=int64)
to something like this:
array([[[ 1, 2, 3],
[-1, -2, -3]],
[[ 2, 3, 4],
[-2, -3, -4]],
[[ 3, 4, 5],
[-3, -4, -5]]], dtype=int64)
Tried to use the reshape function, but that didnt work for me.
thanks
Just np.stack along axis 1:
arr = np.array([[[ 1, 2, 3],
[ 2, 3, 4],
[ 3, 4, 5]],
[[-1, -2, -3],
[-2, -3, -4],
[-3, -4, -5]]])
np.stack(arr, 1)
results in
array([[[ 1, 2, 3],
[-1, -2, -3]],
[[ 2, 3, 4],
[-2, -3, -4]],
[[ 3, 4, 5],
[-3, -4, -5]]])
This would work:
import numpy as np
x = np.array([[[ 1, 2, 3],
[ 2, 3, 4],
[ 3, 4, 5]],
[[-1, -2, -3],
[-2, -3, -4],
[-3, -4, -5]]], dtype=np.int64)
np.vstack(map(lambda x: [x], zip(*(x))))
array([[[ 1, 2, 3],
[-1, -2, -3]],
[[ 2, 3, 4],
[-2, -3, -4]],
[[ 3, 4, 5],
[-3, -4, -5]]], dtype=int64)
You should be able to use use the numpy.reshape function without any error.
Here's how:
a = array([[[ 1, 2, 3],
[ 2, 3, 4],
[ 3, 4, 5]],
[[-1, -2, -3],
[-2, -3, -4],
[-3, -4, -5]]], dtype=int64)
a = a.reshape(3, 2, 3)
Here's what array 'a' will be converted into:
array([[[ 1 2 3]
[ 2 3 4]]
[[ 3 4 5]
[-1 -2 -3]]
[[-2 -3 -4]
[-3 -4 -5]]])
This isn't a reshape problem. It's transpose task - reordering the axes:
In [293]: arr.transpose(1,0,2)
Out[293]:
array([[[ 1, 2, 3],
[-1, -2, -3]],
[[ 2, 3, 4],
[-2, -3, -4]],
[[ 3, 4, 5],
[-3, -4, -5]]])
stack works by iterating on the first dimension, and concatenating on a new middle axis. transpose just makes a view so will be faster.
I have an array a in Python, let's say a=np.array([3, 4]), and would like to define an ndarray (or something like that) of type [-3:3, -4:4], in other words, a collection x of real numbers x[-3,-4], x[-3,-3],...,x[3,4], the i'th coordinate ranging over integers between -a[i] and a[i]. If the array length is given (2 in this example), I could use
np.mgrid[-a[0]:a[0]:1.0,-a[1]:a[1]:1.0][0].
But what should I do if the length of a is unknown?
You could generate a list of ranges with
[np.arange(-x,x+1) for x in a]
I'd have to play around with mgrid, or another function in index_tricks to figure how to use it. I may to make it a tuple or pass it with a *.
mgrid wants slices, so this would replicate your first call
In [60]: np.mgrid[[slice(-x,x+1) for x in [3,4]]]
Out[60]:
array([[[-3, -3, -3, -3, -3, -3, -3, -3, -3],
[-2, -2, -2, -2, -2, -2, -2, -2, -2],
[-1, -1, -1, -1, -1, -1, -1, -1, -1],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 2, 2, 2, 2, 2, 2, 2, 2, 2],
[ 3, 3, 3, 3, 3, 3, 3, 3, 3]],
[[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4]]])
which of course can be generalized to use a.
My initial arange approach works with meshgrid (producing a list of arrays):
In [71]: np.meshgrid(*[np.arange(-x,x+1) for x in [3,4]],indexing='ij')
Out[71]:
[array([[-3, -3, -3, -3, -3, -3, -3, -3, -3],
[-2, -2, -2, -2, -2, -2, -2, -2, -2],
...
[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4],
[-4, -3, -2, -1, 0, 1, 2, 3, 4]])]
I need to find the indicies of both the zero and nonzero elements of an array.
Put another way, I want to find the complementary indices from numpy.nonzero().
The way that I know to do this is as follows:
indices_zero = numpy.nonzero(array == 0)
indices_nonzero = numpy.nonzero(array != 0)
This however means searching the array twice, which for large arrays is not efficient. Is there an efficient way to do this using numpy?
Assuming you already have the range for use numpy.arange(len(array)), just get and store the logical indices:
bindices_zero = (array == 0)
then when you actually need the integer indices you can do
indices_zero = numpy.arange(len(array))[bindices_zero]
or
indices_nonzero = numpy.arange(len(array))[~bindices_zero]
You can use boolean indexing:
In [82]: a = np.random.randint(-5, 5, 100)
In [83]: a
Out[83]:
array([-2, -1, 4, -3, 1, -2, 2, -1, 2, -1, -3, 3, -3, -4, 1, 2, 1,
3, 3, 0, 1, -3, -4, 3, -5, -1, 3, 2, 3, 0, -5, 4, 3, -5,
-3, 1, -1, 0, -4, 0, 1, -5, -5, -1, 3, -2, -5, -5, 1, 0, -1,
1, 1, -1, -2, -2, 1, 1, -4, -4, 1, -3, -3, -5, 3, 0, -5, -2,
-2, 4, 1, -4, -5, -1, 3, -3, 2, 4, -4, 4, 2, -2, -4, 3, 4,
-2, -4, 2, -4, -1, 0, -3, -1, 2, 3, 1, 1, 2, 1, 4])
In [84]: mask = a != 0
In [85]: a[mask]
Out[85]:
array([-2, -1, 4, -3, 1, -2, 2, -1, 2, -1, -3, 3, -3, -4, 1, 2, 1,
3, 3, 1, -3, -4, 3, -5, -1, 3, 2, 3, -5, 4, 3, -5, -3, 1,
-1, -4, 1, -5, -5, -1, 3, -2, -5, -5, 1, -1, 1, 1, -1, -2, -2,
1, 1, -4, -4, 1, -3, -3, -5, 3, -5, -2, -2, 4, 1, -4, -5, -1,
3, -3, 2, 4, -4, 4, 2, -2, -4, 3, 4, -2, -4, 2, -4, -1, -3,
-1, 2, 3, 1, 1, 2, 1, 4])
In [86]: a[-mask]
Out[86]: array([0, 0, 0, 0, 0, 0, 0])
I'm not sure about a built-in numpy method for accomplishing this, but you could use an old-fashioned for loop, I believe. Something like:
indices_zero = []
indices_nonzero = []
for index in xrange(len(array)):
if array[index] == 0:
indicies_zero.append(index)
else:
indicies_nonzero.append(index)
Something like this should accomplish what you want, by only looping once.