Generate (NxN) array from (Nx1) array in Python - python

Consider the following (Nx1) array:
a = [[1]
[2]
[3]
[4]
[5]]
How to generate an (NxN) array from a? For e.g. N = 5:
a = [[1 1 1 1 1]
[2 2 2 2 2]
[3 3 3 3 3]
[4 4 4 4 4]
[5 5 5 5 5]]

If you want to copy the values, you can use np.repeat:
>>> np.repeat(a, len(a), 1)
array([[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4],
[5, 5, 5, 5, 5]])
Else, you should perform a broadcast and wrap a with a view using np.broadcast_to:
>>> np.broadcast_to(a, (len(a),)*2)
array([[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4],
[5, 5, 5, 5, 5]])

You can do it like this:
a = [[1], [2], [3], [4], [5]]
out = []
for el in a:
out.append(el * len(a))
return out
It is even better if you compute the length of the 'a' list once at the beginning.

A pythonic one liner to generate the two dimensional array
a = [[1], [2], [3], [4], [5]]
N = 5
x = [i * N for i in a]
Sources:
Python List Comprehensions
How can I define multidimensional arrays in python?

Related

Convert one-dimensional array to two-dimensional array so that each element is a row in the result

I want to know how to convert this: array([0, 1, 2, 3, 4, 5]) to this:
array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4],
[5, 5, 5]])
In short, given a flat array, repeat each element inside the array n times, so that each element creates a sub-array of n of the same element, and concatenate these sub-arrays into one, so that each row contains an element from the original array repeated n times.
I can do this:
def repeat(lst, n):
return [[e]*n for e in lst]
>repeat(range(10), 4)
[[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
[5, 5, 5, 5],
[6, 6, 6, 6],
[7, 7, 7, 7],
[8, 8, 8, 8],
[9, 9, 9, 9]]
How to do this in NumPy?
You can use numpy's repeat like this:
np.repeat(range(10), 4).reshape(10,4)
which gives:
[[0 0 0 0]
[1 1 1 1]
[2 2 2 2]
[3 3 3 3]
[4 4 4 4]
[5 5 5 5]
[6 6 6 6]
[7 7 7 7]
[8 8 8 8]
[9 9 9 9]]
You can use tile that handles dimensions:
a = np.array([0, 1, 2, 3, 4, 5])
N = 4
np.tile(a[:,None], (1, N))
# or
np.tile(a, (N, 1)).T
or broadcast_to:
np.broadcast_to(a, (N, a.shape[0])).T
# or
np.broadcast_to(a[:,None], (a.shape[0], N))
Or multiply by an array of ones:
a[:,None]*np.ones(N, dtype=a.dtype)
output:
array([[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
[5, 5, 5, 5]])

variable access between Function calls behavior in Python

I am doing recursion and storing the value in every step if calling.
Like if my working program-code is like-
lst=[]
def after_occurance(ls,l,curr):
for i in range(l,curr):
if ls[i]==ls[curr]:
return False
return True
def permutate(A,l,r):
if l==r:
ans=A.copy()
print(A,ans)
# change the commenting of the following 2 lines to see the difference
lst.append(A)
#lst.append(ans)
print(lst)
return lst
else:
for i in range(l,r+1):
if after_occurance(A,l,i):
A[i],A[l] = A[l],A[i]
permutate(A,l+1,r)
hm[A[l]]=1
A[l],A[i] = A[i],A[l]
else:
continue
lst.clear()
A=[1,2,6]
A=sorted(A)
permutate(A,0,len(A)-1)
return lst
Following are 2 kind of outputs when Toggling between 2 commented line respectively
[1, 2, 6] [1, 2, 6]
[[1, 2, 6]]
[1, 6, 2] [1, 6, 2]
[[1, 2, 6], [1, 6, 2]]
[2, 1, 6] [2, 1, 6]
[[1, 2, 6], [1, 6, 2], [2, 1, 6]]
[2, 6, 1] [2, 6, 1]
[[1, 2, 6], [1, 6, 2], [2, 1, 6], [2, 6, 1]]
[6, 2, 1] [6, 2, 1]
[[1, 2, 6], [1, 6, 2], [2, 1, 6], [2, 6, 1], [6, 2, 1]]
[6, 1, 2] [6, 1, 2]
[[1, 2, 6], [1, 6, 2], [2, 1, 6], [2, 6, 1], [6, 2, 1], [6, 1, 2]]
[1 2 6 ] [1 6 2 ] [2 1 6 ] [2 6 1 ] [6 1 2 ] [6 2 1 ]
[1, 2, 6] [1, 2, 6]
[[1, 2, 6]]
[1, 6, 2] [1, 6, 2]
[[1, 6, 2], [1, 6, 2]]
[2, 1, 6] [2, 1, 6]
[[2, 1, 6], [2, 1, 6], [2, 1, 6]]
[2, 6, 1] [2, 6, 1]
[[2, 6, 1], [2, 6, 1], [2, 6, 1], [2, 6, 1]]
[6, 2, 1] [6, 2, 1]
[[6, 2, 1], [6, 2, 1], [6, 2, 1], [6, 2, 1], [6, 2, 1]]
[6, 1, 2] [6, 1, 2]
[[6, 1, 2], [6, 1, 2], [6, 1, 2], [6, 1, 2], [6, 1, 2], [6, 1, 2]]
[1 2 6 ] [1 2 6 ] [1 2 6 ] [1 2 6 ] [1 2 6 ] [1 2 6 ]
Can somebody explain this behavior and what basic rule should I follow while doing Recursive calls and variable access in python?
So, this is the code you really wanted to post:
def after_occurance(ls, l, curr):
for i in range(l, curr):
if ls[i] == ls[curr]:
return False
return True
def permutate(A, l, r):
if l == r:
ans = A.copy()
# change the commenting of the following 2 lines to see the difference
#lst.append(A)
lst.append(ans)
return
else:
for i in range(l, r + 1):
if after_occurance(A, l, i):
A[i],A[l] = A[l],A[i]
permutate(A, l + 1, r)
A[l],A[i] = A[i],A[l]
else:
continue
lst = []
A = [1,2,6]
A = sorted(A)
permutate(A, 0, len(A) - 1)
print(lst)
The difference comes from appending a copy() of A or just a reference to A.
When you append a reference to A, all the future changes to A show up in lst because the result is lst = [A, A, A, A, A, ....] and so lst cannot be anything apart from a list of the same thing.
When you append a copy() of A, you make a new list which is not changed after the append() and so records the history of how A looked over time.

numpy. Sum multidimensional array at specific indexes

I'm trying to replace something like this code, for a vectorized efficient operation using numpy.
counter = 0
idxs = [1, 3]
lists = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
for l in lists:
for idx in idxs:
counter += l[idx]
Just sum the array:
idxs = [1, 3]
lists = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
ary = np.array(lists)
counter = ary[:,idxs].sum()

Building a matrix of 'rolled' rows efficiently in Numpy

I'd like to construct a (n,n)-array from a one dimensional array, where each row is shifted (with wrapping) by one relative to the previous one. The following code does this:
import numpy as np
r = np.array([1, 2, 3, 4, 5])
n = len(r)
MM = np.zeros((n, n), dtype=r.dtype)
for k in range(n):
MM[k, :] = np.roll(r, k)
print(MM)
which results in:
[[1 2 3 4 5]
[5 1 2 3 4]
[4 5 1 2 3]
[3 4 5 1 2]
[2 3 4 5 1]]
Is there a way to do this Numpy faster, i.e., avoiding the for-loop, for large r in Numpy?
Take a look at scipy.linalg.circulant
In [255]: r
Out[255]: array([1, 2, 3, 4, 5])
In [256]: circulant(r).T
Out[256]:
array([[1, 2, 3, 4, 5],
[5, 1, 2, 3, 4],
[4, 5, 1, 2, 3],
[3, 4, 5, 1, 2],
[2, 3, 4, 5, 1]])
or scipy.linalg.toeplitz
In [257]: toeplitz(np.roll(r[::-1], 1), r)
Out[257]:
array([[1, 2, 3, 4, 5],
[5, 1, 2, 3, 4],
[4, 5, 1, 2, 3],
[3, 4, 5, 1, 2],
[2, 3, 4, 5, 1]])

filter numpy array by another array of different shape

Given:
a = [[0, 1], [2, 2], [4, 2]]
b = [[0, 1, 2, 3], [2, 2, 3, 4], [4, 2, 3, 3], [2, 3, 3, 3]]
Solution is:
for (i,j) in zip(a[:, 0], a[:, 1]):
print b[np.logical_and( a[:, 0] == i, a[:, 1] == j)]
Result should be
[[0 1 2 3]]
[[2 2 3 4]]
[[4 2 3 3]]
Is there any solution for this problem without use of the for-loop?
You can use NumPy broadcasting for a vectorized solution, like so -
# 2D mask corresponding to all iterations of :
# "np.logical_and( a[:, 0] == i, a[:, 1] == j)"
mask = (a[:,None,0] == a[:,0]) & (a[:,None,1] == a[:,1])
# Use column indices of valid ones for indexing into b for final output
_,C_idx = np.where(mask)
out = b[C_idx]
Sample run -
In [67]: # Modified generic case
...: a = np.array([[0, 1], [3, 2], [3, 2]])
...: b = np.array([[0, 1, 2, 3], [2, 2, 3, 4], [4, 2, 3, 3], [2, 3, 3, 3]])
...:
...: for (i,j) in zip(a[:, 0], a[:, 1]):
...: print b[np.logical_and( a[:, 0] == i, a[:, 1] == j)]
...:
[[0 1 2 3]]
[[2 2 3 4]
[4 2 3 3]]
[[2 2 3 4]
[4 2 3 3]]
In [68]: mask = (a[:,None,0] == a[:,0]) & (a[:,None,1] == a[:,1])
...: _,C_idx = np.where(mask)
...: out = b[C_idx]
...:
In [69]: out
Out[69]:
array([[0, 1, 2, 3],
[2, 2, 3, 4],
[4, 2, 3, 3],
[2, 2, 3, 4],
[4, 2, 3, 3]])
Given:
a = np.array(([0, 1], [2, 2], [4, 2]))
b = np.array(([0, 1, 2, 3], [2, 2, 3, 4], [4, 2, 3, 3], [2, 3, 3, 3]))
Calculate:
temp = np.in1d(b[:,0], a[:,0]) * np.in1d(b[:,1], a[:,1])
result = b[temp]
print 'result:', result
Output:
result: [[0 1 2 3]
[2 2 3 4]
[4 2 3 3]]

Categories

Resources