Any clustering algorithms for points which are equidistant apart, holding different values? - cluster-analysis

I have a data set with equidistant points with different values, like a 2D matrix, for example:
[[1, 2, 1, 5, 6]
[2, 1, 4, 7, 6],
[5, 1, 9, 3, 7]]
I want to do clustering based on the value, but with the points being spatially (equidistant) constrained. I plot this data in a colourmap, so perhaps to group the data based on values close to each other.
Are there any algorithms for this?
(Edited for clarity)

Maybe you should try skimage.slic or a similar algorithm from the example in skimage.segmentation
import numpy as np
from skimage import segmentation
a = np.array([[1, 2, 1, 5, 6],
[2, 1, 4, 7, 6],
[5, 1, 9, 3, 7]])
segments = segmentation.slic(a, n_segments=4)
print(segments)
>>> [[0 0 1 1 2]
[0 0 1 1 2]
[3 3 4 4 5]]
You can then adjust the compactness and number of segments to your need

Related

how do I concatenate the results of a concatenated array?

I have two matrices (dfs):
A = [1 2 3 4
5 6 7 8
9 10 11 12]
and B = [1, 2, 3]
and I want matrix C to be repeating each row in A, B times. for example, first row, 1,2,3,4 needs to be repeated once, second row: 5,6,7,8 twice and last row three times:
C = [1 2 3 4
5 6 7 8
5 6 7 8
9 10 11 12
9 10 11 12
9 10 11 12]
my code
for i in range(0,2401):
g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True)
partially does this, except only gives me the 3 times last row part, I need to concatenate each concatenation.
below gives me what I want but its not clean, i.e. indices are not ignored and messy.
result = []
for i in range(0,2401):
g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True)
result.append(g)
If you write your matrices like:
A = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
B = [1, 2, 3]
C = []
You can iterate through B and add to C like:
for i in range(len(B)):
index = 0
while index < B[i]:
C.append(A[i])
index += 1
Which has an output:
[[1, 2, 3, 4],
[5, 6, 7, 8],
[5, 6, 7, 8],
[9, 10, 11, 12],
[9, 10, 11, 12],
[9, 10, 11, 12]]
I hope this helps!

Getting the matrix value given a vector of indices along each axis

I have a Matlab matrix M with size: [70 5 3 2 10 9 5 3 21];
I have a vector with a coordinates that I want to read of that matrix: [5, 1, 1, 2, 3, 4, 1, 2, 1];
MWE example of what I am trying to get:
M = rand(70 5 3 2 10 9 5 3 21);
coordinates = [5, 1, 1, 2, 3, 4, 1, 2, 1];
% Output desired:
M(5, 1, 1, 2, 3, 4, 1, 2, 1)
%Current attempt:
M(coordinates)
Clearly M(coordinates) <> M(5, 1, 1, 2, 3, 4, 1, 2, 1). Is there a way of doing this?
It's a bit awkward, but you can convert the array to a cell array, and then to a comma-separated list:
M = rand(70, 5, 3, 2, 10, 9, 5, 3, 21);
coordinates = [5, 1, 1, 2, 3, 4, 1, 2, 1];
coords_cell = num2cell(coordinates);
result = M(coords_cell{:});

Reproduce the pseudo-random numbers of Matlab's randi with numpy.random

I need to reproduce many pseudo-random matrices generated with Matlab's randi function for fixed seeds.
To give a simple example, I want to reproduce
>> rng(2);
>> randi([-10, 10], 4, 4)
ans =
-1 -2 -4 -8
-10 -4 -5 0
1 -6 3 -7
-1 3 1 6
According to the docs, Matlab's randi uses the Mersenne Twister random number generator. Here's what I tried so far with numpy:
In [2]: np.random.seed(2)
In [3]: np.random.randint(-10, 11, size=(4,4))
Out[3]:
array([[-2, 5, 3, -2],
[ 1, 8, 1, -2],
[-3, -8, 7, 1],
[ 5, 10, 10, -5]])
In [5]: from numpy.random import MT19937
In [6]: from numpy.random import RandomState, SeedSequence
In [7]: rs = RandomState(MT19937(SeedSequence(2)))
In [8]: rs.randint(-10, 11, size=(4,4))
Out[8]:
array([[-10, 0, -6, -3],
[ -2, 8, -10, -8],
[ -1, -6, 10, 6],
[ 9, 1, -6, 0]])
Any ideas?
I'm aware that I could export the matrices from matlab to Python, but I want to reproduce the same pseudo-random numbers.

How to check if a list of lists contains any of the elements from another list

I'm trying to make a sample lottery checker.
I'm using python.
x = [1,2,3,4,5,
y = [[1,2,3,4,5,6] # 6 numbers hit
,[1,2,3,4,6,7] # 5 numbers hit
,[2,3,4,6,7,8] # 4 numbers hit
,[4,5,6,7,8,9] # 3 numbers hit
,[1,2,7,8,9,10] # 2 numbers hit
,[4,7,8,9,10,11] # 1 number hit
,[7,8,9,10,11,12]]
output: (including the number of hits)
[1,2,3,4,5,6] 6 number hit
[1,2,3,4,6,7] 5 numbers hit
[2,3,4,6,7,8] 4 numbers hit
[4,5,6,7,8,9] 3 numbers hit
[1,2,7,8,9,10] 2 numbers hit
[4,7,8,9,10,11] 1 number hit
I tried using the any() function but only returned true or false.
please help.
Data:
x = [1,2,3,4,5,6]
y = [[1,2,3,4,5,6] # 6 numbers hit
,[1,2,3,4,6,7] # 5 numbers hit
,[2,3,4,6,7,8] # 4 numbers hit
,[4,5,6,7,8,9] # 3 numbers hit
,[1,2,7,8,9,10] # 2 numbers hit
,[4,7,8,9,10,11] # 1 number hit
,[7,8,9,10,11,12]]
Code:
for ticket in y:
print(ticket)
count = 0
for item in x:
if item in ticket:
count += 1
print(count, " numbers hit!")
Output:
[1, 2, 3, 4, 5, 6]
6 numbers hit!
[1, 2, 3, 4, 6, 7]
5 numbers hit!
[2, 3, 4, 6, 7, 8]
4 numbers hit!
[4, 5, 6, 7, 8, 9]
3 numbers hit!
[1, 2, 7, 8, 9, 10]
2 numbers hit!
[4, 7, 8, 9, 10, 11]
1 numbers hit!
[7, 8, 9, 10, 11, 12]
0 numbers hit!

Expanding each element in a (2-by-2) matrix to a (3-by-2) block

I want to expand each element in a (2-by-2) matrix to a (3-by-2) block, using Python 3 --- with professional and elegant codes. Since I don't know the python codes, I will just describe the following in maths
X = # X is an 2-by-2 matrix.
1, 2
3, 4
d = (3,2) # d is the shape that each element in X should be expanded to.
Y = # Y is the result
1, 1, 2, 2
1, 1, 2, 2
1, 1, 2, 2
3, 3, 4, 4
3, 3, 4, 4
3, 3, 4, 4
Not that every element in X is now an 3-by-2 block in Y. The position of the block in Y is the same as the position of the element in X.
Here is the MATLAB code
X = [1,2;3,4];
d = [3,2]
[row, column] = size(X);
a = num2cell(X);
b = cell(row, column);
[b{:}] = deal(ones(d));
Y = cell2mat(cellfun(#times,a,b,'UniformOutput',false));
I appreciate your help. Thanks in advance.
If you are okay with using NumPy module with Python, you can use numpy.kron -
np.kron(X,np.ones((3,2),dtype=int))
Sample run -
In [15]: import numpy as np
In [16]: X = np.arange(4).reshape(2,2)+1 # Create input array
In [17]: X
Out[17]:
array([[1, 2],
[3, 4]])
In [18]: np.kron(X,np.ones((3,2),dtype=int))
Out[18]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4],
[3, 3, 4, 4]])
In fact, this is a direct translation of how one would achieved the desired result in MATLAB in an elegant and professional way as well, as shown below -
>> X = [1,2;3 4]
X =
1 2
3 4
>> kron(X,ones(3,2))
ans =
1 1 2 2
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
3 3 4 4
Another way to do it with ndarray.repeat:
>>> X = np.arange(4).reshape(2,2)+1
>>> X.repeat(3, axis=0).repeat(2, axis=1)
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4],
[3, 3, 4, 4]])