# 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. – Peter Jun 1 '19 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 '19 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 '19 at 22:38
• I will check your suggestion If it could help me – rima Jun 1 '19 at 22:40
• Have a look at time series segmentation/jump algorithms. – Edmund Jun 8 '19 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]