# Is there a scientific method for grouping continuous numbers for this problem

I use python, and I have a list of numbers that contains 19 elements and I would like to divide this list into 6 groups or fewer.

The list could have numbers between 0 and 1. and it mustn't be ordered, I need to keep it on its form and getting cut-off

list:

Numbers :  [[ 0.867   - 0.808   - 0.740    - 0.746    - 0.674   - 0.669   -
0.648   - 0.722   - 0.781    - 0.612    - 0.575   - 0.566   -
0.500   - 0.555   - 0.818    - 0.800    - 0.500   - 0.500   - 0.666 ]]


I would like to get clusters like :

A: [[ 0.867   - 0.808   - 0.740    - 0.746 ]]

B: [[ 0.674   - 0.669   - 0.648 ]]

C: [[ 0.722   - 0.781 ]]

D: [[ 0.612   - 0.575   - 0.566    - 0.500    - 0.555  ]]

E: [[ 0.818   - 0.800 ]]

F: [[ 0.500   - 0.500    - 0.666 ]]


I make splitting by eyes and for that, I ask for a scientific method for getting my objective.

• Concerning how I defined these clusters :

I have a value that is getting from an extra function, it is equal to 0.80. I need to compare each value on the list with 0.80 for knowing the difference.

After making a comparison I get the following table

Numbers      Difference_0.80
0.867            +0.06
0.808             0.0
0.740            -0.06
0.746            -0.06

0.674            -0.13
0.669            -0.14
0.648            -0.16

0.722            -0.08
0.781            -0.02

0.612            -0.19
0.575            -0.23
0.566            -0.24
0.500            -0.3
0.555            -0.25

0.818            +0.01
0.800             0.0

0.500            -0.3
0.500            -0.3
0.666            -0.14



when I tried clustering method (with n_clusters=2) I ve got :

0   category_Kk-mean
0.867   0
0.808   0
0.740   0
0.746   0
0.674   1
0.669   1
0.648   1
0.722   0
0.781   0
0.612   1
0.575   1
0.566   1
0.500   1
0.555   1
0.818   0
0.800   0
0.500   1
0.500   1
0.666   1



But I want to know also that this category (D) have a big decrease than a category (B):

category D
0.612   1
0.575   1
0.566   1
0.500   1
0.555   1

Category B

0.674   1
0.669   1
0.648   1


I tried with n_clusters=3 but I got a totaly bad result

Is there any method in the statistic or mathematic that can help me for getting that

• I don‘t understand your question. Do you want to group „closest numbers“ based on a predefined number of groups. In this case you can simply build groups based on the distribution of numbers. So, say two groups, means split by median. Jun 1, 2019 at 21:44
• I have a list of numbers that contains an increase and decrease percentages. The original value is 0.80. I want to keep the table without making any order. and I want to know when to start the next decrease and when it is finished and the same thing for increases categories.
– rima
Jun 1, 2019 at 22:38
• but if there is a category that contains a small decrease percentage and that is placed between 2 categories which contain both a big decrease like category C It should be considerate as increase
– rima
Jun 1, 2019 at 22:38
• I will check your suggestion If it could help me
– rima
Jun 1, 2019 at 22:40
• Have a look at time series segmentation/jump algorithms. Jun 8, 2019 at 16:46

Because you care about the ordering you can represent your points in two dimensions (where the x coordinate is just rescaled sequence number) and apply K-means.


import numpy as np

numbers = np.array([0.867, 0.808, 0.740, 0.746, 0.674,
0.669, 0.648, 0.722, 0.781, 0.612,
0.575, 0.566, 0.500, 0.555, 0.818,
0.800, 0.500, 0.500, 0.666])

#you can experiment with other step sizes
step_size = (numbers.max() - numbers.min())/len(numbers)
numbers2d = np.array([(step_size * i,x) for (i,x) in enumerate(numbers - 0.8)])

from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=6)
kmeans.fit(numbers2d) #random init - possibly different result each time

print(kmeans.labels_)

import matplotlib.pyplot as plt

for cluster in set(kmeans.labels_):
x = np.where(kmeans.labels_==cluster)[0]
y = numbers[x]
x = numbers2d[:,0][x]
plt.scatter(x,y)

plt.show()


Output:

[3 3 3 3 1 1 1 1 1 4 4 4 4 4 5 5 2 2 0]