Determining if an array inside an array is contiguous - python

Firstly, I start with sorted trial data:
[[ 2, 4, 9, 10, 11],
[ 2, 6, 7, 8, 14],
[ 3, 6, 8, 8, 11],
[ 4, 6, 10, 11, 13],
[ 2, 3, 3, 5, 6],
[ 3, 5, 12, 12, 13],
[ 2, 2, 3, 9, 11],
[ 2, 5, 11, 11, 13],
[ 3, 5, 7, 9, 10],
[ 2, 6, 7, 8, 14]]
Then my goal is return a True or False in the place of each array within and then print out the number of True (contiguous arrays)
So far, I have done this:
def isStraight(arr, n):
for i in range(1,n):
if (arr[i] - arr[i-1] > 1) :
return 0
return 1
but it returns an error saying
The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
So I am not sure how to implement another for loop to iterate through the internal arrays. Any help would be appreciated.

I am assuming that the array is contiguous if any consecutive elements are with a difference of more than 1, with this try the below code:
a =[[ 2, 4, 9, 10, 11],
[ 2, 6, 7, 8, 14],
[ 3, 6, 8, 8, 11],
[ 4, 6, 10, 11, 13],
[ 2, 3, 3, 5, 6],
[ 3, 5, 12, 12, 13],
[ 2, 2, 3, 9, 11],
[ 2, 5, 11, 11, 13],
[ 3, 5, 7, 9, 10],
[ 2, 6, 7, 8, 14]]
def isStraight(arr, n):
for i in range(1,n):
if (arr[i] - arr[i-1] > 1) :
return 0
return 1
values = []
for j in a:
if(isStraight(j, len(j))==1):
values.append(True)
else:
values.append(False)
print(values)

The output of this code contains a list of true and false. True, indicates that its corresponding array is continuous, and false indicates that its corresponding array is non-continuous. Finally, the number of continuous arrays is shown.
def contiguous_arrays(array):
value=[]
for i in range(len(array)):
value.append(array[i]==list(range(min(array[i]),max(array[i])+1)))
print(value)
print('Number of continuous arrays:',value.count(True))
array=[[ 2, 4, 9, 10, 11],
[ 2, 6, 7, 8, 14],
[ 3, 6, 8, 8, 11],
[ 4, 6, 10, 11, 13],
[ 2, 3, 3, 5, 6],
[ 3, 5, 12, 12, 13],
[ 2, 2, 3, 9, 11],
[ 2, 5, 11, 11, 13],
[ 3, 5, 7, 9, 10],
[ 2, 6, 7, 8, 14]]
contiguous_arrays(array)
# [False, False, False, False, False, False, False, False, False, False] Number of continuous arrays: 0

Related

How to make a 2d numpy array from an empty numpy array by adding 1d numpy arrays?

So I'm trying to start an empty numpy array with a = np.array([]), but when i append other numpy arrays (like [1, 2, 3, 4, 5, 6, 7, 8] and [9, 10, 11, 12, 13, 14, 15, 16] to this array, then the result im basically getting is
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].
But what i want as result is: [[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16]]
IIUC you want to keep adding lists to your np.array. In that case, you can use something like np.vstack to "append" the new lists to the array.
a = np.array([[1, 2, 3],[4, 5, 6]])
np.vstack([a, [7, 8, 9]])
>>> array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
You can also use np.c_[], especially if a and b are already 1D arrays (but it also works with lists):
a = [1, 2, 3, 4, 5, 6, 7, 8]
b = [9, 10, 11, 12, 13, 14, 15, 16]
>>> np.c_[a, b]
array([[ 1, 9],
[ 2, 10],
[ 3, 11],
[ 4, 12],
[ 5, 13],
[ 6, 14],
[ 7, 15],
[ 8, 16]])
It also works "multiple times":
>>> np.c_[np.c_[a, b], a, b]
array([[ 1, 9, 1, 9],
[ 2, 10, 2, 10],
[ 3, 11, 3, 11],
[ 4, 12, 4, 12],
[ 5, 13, 5, 13],
[ 6, 14, 6, 14],
[ 7, 15, 7, 15],
[ 8, 16, 8, 16]])

Python: how to select contiguity neighbors of matrix values?

I have a matrix like the following:
A = array([[12, 6, 14, 8, 4, 1],
[18, 13, 8, 10, 9, 19],
[ 8, 15, 6, 5, 6, 18],
[ 3, 0, 2, 14, 13, 12],
[ 4, 4, 5, 19, 0, 14],
[16, 8, 7, 7, 11, 0],
[ 3, 11, 2, 19, 11, 5],
[ 4, 2, 1, 9, 12, 12]])
For each cell I want to select the values in a radius of k=2 closest cells.
For instance if I select the A[3,4] I would like a submatrix like the following
array([[18, 13, 8, 10, 9],
[ 8, 15, 6, 5, 6],
[ 3, 0, 2, 14, 13],
[ 4, 4, 5, 19, 0],
[16, 8, 7, 7, 11]])
I defined the following function
def queen_neighbourhood(Adj, in_row, in_col, k):
j=k
k+=1
neighbourhood = Adj[in_row-j:in_row+k, in_col-j:in_col+k]
return neighbourhood
such as queen_neighbourhood(A, 3, 2, 2) returns
array([[18, 13, 8, 10, 9],
[ 8, 15, 6, 5, 6],
[ 3, 0, 2, 14, 13],
[ 4, 4, 5, 19, 0],
[16, 8, 7, 7, 11]])
However it does not work in borders.
For instance, for the cell [0,0] I would like to have
array([[12, 6, 14],
[18, 13, 8],
[ 8, 15, 16])
but it returns queen_neighbourhood(A, 0, 0, 2)
array([], shape=(0, 0), dtype=int64)
You could avoid negative indices:
neighbourhood = Adj[max(in_row-j, 0) : in_row+k,
max(in_col-j, 0) : in_col+k]
Adding to the previous answer; taking into consideration the extreme values
def queen_neighbourhood(Adj, in_row, in_col, k):
j=k
k+=1
neighbourhood = Adj[max(in_row-j, 0) : min(in_row+k,Adj.shape[0]),
max(in_col-j, 0) : min(in_col+k,Adj.shape[1])]
return(neighbourhood)
You can use numpy roll to ensure you are always dealing with the middle value,
import numpy as np
def queen_neighbourhood(Adj, in_row, in_col, k):
j=k
k+=1
midrow = int(Adj.shape[0]/2.)+1
midcol = int(Adj.shape[1]/2.)+1
Ashift = np.roll(Adj,(in_row-midrow,in_col-midcol),(0,1))
neighbourhood = Ashift[1:k+1, 1:k+1]
return neighbourhood
A = np.array([[18, 13, 8, 10, 9],
[ 8, 15, 6, 5, 6],
[ 3, 0, 2, 14, 13],
[ 4, 4, 5, 19, 0],
[16, 8, 7, 7, 11]])
print(A)
An = queen_neighbourhood(A, 0, 0, 2)
print(An)
which gives,
[[11 16 8]
[ 9 18 13]
[ 6 8 15]]

set values of 2D numpy array by parameters

I need to create 2D np array by the known shape and parameters in this way:
import numpy as np
rows = 9
cols = 8
xrows = 3
xcols = 2
the wanted results:
([[ 1, 1, 4, 4, 7, 7, 10, 10],
[ 1, 1, 4, 4, 7, 7, 10, 10],
[ 1, 1, 4, 4, 7, 7, 10, 10],
[ 2, 2, 5, 5, 8, 8, 11, 11],
[ 2, 2, 5, 5, 8, 8, 11, 11],
[ 2, 2, 5, 5, 8, 8, 11, 11],
[ 3, 3, 6, 6, 9, 9, 12, 12],
[ 3, 3, 6, 6, 9, 9, 12, 12],
[ 3, 3, 6, 6, 9, 9, 12, 12]])
rows%xrows = 0
cols%xcols = 0
rows is the number of rows of the array, cols is the number of columns of the array, xrows is the number of rows in each slice, xcols is the number of column in each slice.
the answer should be general not for this parameters
IIUC, you can use:
((np.arange(rows//xrows*cols//xcols, dtype=int)+1)
.reshape((rows//xrows,cols//xcols), order='F')
.repeat(xrows,0)
.repeat(xcols,1)
)
Output:
array([[ 1, 1, 4, 4, 7, 7, 10, 10],
[ 1, 1, 4, 4, 7, 7, 10, 10],
[ 1, 1, 4, 4, 7, 7, 10, 10],
[ 2, 2, 5, 5, 8, 8, 11, 11],
[ 2, 2, 5, 5, 8, 8, 11, 11],
[ 2, 2, 5, 5, 8, 8, 11, 11],
[ 3, 3, 6, 6, 9, 9, 12, 12],
[ 3, 3, 6, 6, 9, 9, 12, 12],
[ 3, 3, 6, 6, 9, 9, 12, 12]])

3D array to 2d array from pandas Python and Numpy

I have created the array from a csv using pandas and numpy.
This is my code that convert 2D csv to 3D array:
>>> import pandas as pd
>>> import numpy as npp
>>> df = pd.read_csv("test.csv")
>>> df_mat = df.values
>>> seq_len = 3
>>> data=[]
>>> for index in range(len(df_mat) - seq_len):
... data.append(df_mat[index: index + seq_len])
...
>>> data = np.array(data)
>>> data.shape
(4, 3, 9)
The csv is used is:
input1,input2,input3,input4,input5,input6,input7,input8,output
1,2,3,4,5,6,7,8,1
2,3,4,5,6,7,8,9,0
3,4,5,6,7,8,9,10,-1
4,5,6,7,8,9,10,11,-1
5,6,7,8,9,10,11,12,1
6,7,8,9,10,11,12,13,0
7,8,9,10,11,12,13,14,1
Now I want to get the 3D array back to 2D array format.
Kindly, let me know how I can I do that. Not getting any clue.
Slice on the 0th rows along each each block until the last block and stack with the last one -
np.vstack((data[np.arange(data.shape[0]-1),0],data[-1]))
Output with given sample data -
In [24]: np.vstack((data[np.arange(data.shape[0]-1),0],data[-1]))
Out[24]:
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 1],
[ 2, 3, 4, 5, 6, 7, 8, 9, 0],
[ 3, 4, 5, 6, 7, 8, 9, 10, -1],
[ 4, 5, 6, 7, 8, 9, 10, 11, -1],
[ 5, 6, 7, 8, 9, 10, 11, 12, 1],
[ 6, 7, 8, 9, 10, 11, 12, 13, 0],
[ 7, 8, 9, 10, 11, 12, 13, 14, 1]], dtype=int64)
Or slice 0th rows across all blocks and stack with the last block skipping the first row -
In [28]: np.vstack((data[np.arange(data.shape[0]),0],data[-1,1:]))
Out[28]:
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 1],
[ 2, 3, 4, 5, 6, 7, 8, 9, 0],
[ 3, 4, 5, 6, 7, 8, 9, 10, -1],
[ 4, 5, 6, 7, 8, 9, 10, 11, -1],
[ 5, 6, 7, 8, 9, 10, 11, 12, 1],
[ 6, 7, 8, 9, 10, 11, 12, 13, 0],
[ 7, 8, 9, 10, 11, 12, 13, 14, 1]], dtype=int64)

Numpy index, get bands of width 2

I am wondering if there is a way it index/slice a numpy array, such that one can get every other band of 2 elements. In other words, given:
test = np.array([[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16]])
I would like to get the array:
[[1, 2, 5, 6],
[9, 10, 13, 14]]
Thoughts on how this can be accomplished with slicing/indexing?
Not that difficult with a few smart reshapes :)
test.reshape((4, 4))[:, :2].reshape((2, 4))
Given:
>>> test
array([[ 1, 2, 3, 4, 5, 6, 7, 8],
[ 9, 10, 11, 12, 13, 14, 15, 16]])
You can do:
>>> test.reshape(-1,2)[::2].reshape(-1,4)
array([[ 1, 2, 5, 6],
[ 9, 10, 13, 14]])
Which works even for different shapes of initial arrays:
>>> test2
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
>>> test2.reshape(-1,2)[::2].reshape(-1,4)
array([[ 1, 2, 5, 6],
[ 9, 10, 13, 14]])
>>> test3
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
>>> test3.reshape(-1,2)[::2].reshape(-1,4)
array([[ 1, 2, 5, 6],
[ 9, 10, 13, 14]])
How it works:
1. Reshape into two columns by however many rows:
>>> test.reshape(-1,2)
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12],
[13, 14],
[15, 16]])
2. Stride the array by stepping every second element
>>> test.reshape(-1,2)[::2]
array([[ 1, 2],
[ 5, 6],
[ 9, 10],
[13, 14]])
3. Set the shape you want of 4 columns, however many rows:
>>> test.reshape(-1,2)[::2].reshape(-1,4)
array([[ 1, 2, 5, 6],
[ 9, 10, 13, 14]])

Categories