В Python предположим, что у меня есть непрерывные переменные x
и y
, значения которых ограничены между 0 и 1 (чтобы было проще).Я всегда предполагал, что если я захочу преобразовать эти переменные в порядковые значения с ячейками, идущими как 0,0.01,0.02, ..., 0.98,0.99,1, можно просто округлить исходные значения до второй цифры.По какой-то причине, когда я это делаю, это оставляет артефакты.
Позвольте мне проиллюстрировать проблему (заметьте, однако, что мой вопрос не в том, как получить правильный график, а на самом деле, как сделать правильное объединение).Во-первых, это единственные модули, которые необходимы для воспроизведения проблемы:
import numpy as np
import matplotlib.pyplot as plt
Теперь предположим, что у нас есть непрерывные данные, сгенерированные следующим образом (другие процессы генерации данных также могут вызвать такую же проблему):
# number of points drawn from Gaussian dists.:
n = 100000
x = np.random.normal(0, 2, n)
y = np.random.normal(4, 5, n)
# normalizing x and y to bound them between 0 and 1
# (it's way easier to illustrate the problem this way)
x = (x - min(x))/(max(x) - min(x))
y = (y - min(y))/(max(y) - min(y))
Затем давайте преобразуем x
и y
в порядковый номер в указанном выше интервале, просто применив некоторое округление.Затем давайте сохраним результаты в матрице x
на y
, чтобы построить ее тепловую карту для целей иллюстрации :
# matrix that will represent the bins. Notice that the
# desired bins are every 0.01, from 0 to 1, so 100 bins:
mtx = np.zeros([100,100])
for i in range(n):
# my idea was that I could roughly get the bins by
# simply rounding to the 2nd decimal point:
posX = round(x[i], 2)
posY = round(y[i], 2)
mtx[int(posX*100)-1, int(posY*100)-1] += 1
Я ожидал, что вышеприведенное сработает, но когдаЯ строю содержимое матрицы mtx
, на самом деле я получаю странные артефакты.Код:
# notice, however, the weird close-to-empty lines at
# 0.30 and 0.59 of both x and y. This happens regardless
# of how I generate x and y. Regardless of distributions
# or of number of points (even if it obviously becomes
# impossible to see if there are too few points):
plt.matshow(mtx, cmap=plt.cm.jet)
plt.show(block=False)
Дает мне:
![enter image description here](https://i.stack.imgur.com/RRuGq.png)
Самое странное, что независимо от того, какой дистрибутив я использую для генерации x
и y
или какое семя я использую для ГСЧ, я всегда получаю одинаковые горизонтальные и вертикальные почти пустые линии в 0,30 и 0,59 как для x
, так и y
, довольно часто, причем линии, непосредственно параллельные этимпоказывает концентрацию точек (как вы видите на картинке).
Когда я печатаю значение по значению из этой матрицы в консоль, я могу фактически подтвердить, что те, которые соответствуют этим почти пустым строкам, действительно либо равны нулюили очень близко к нулю - в отличие от соседних точек.
Мой вопрос может быть более правильно разделен на 2 части:
Почему это произойдет?Я искренне хотел бы понять, что именно создает такую проблему в этом простом коде.
Что было бы лучшим способом сгенерировать матрицу x
с помощью y
, который объединяет значения в соответствии с точками отсечения 0,0.01,0.02, ..., 0,98,0,99,1, не оставляя артефактов выше?
Если кто-то хочет легко захватить всеПример кода, использованного выше непосредственно в одной части, вот ссылка: https://www.codepile.net/pile/VLAq4kLp
ПРИМЕЧАНИЕ: я не хочу найти правильный способ построения.Я хочу найти myeself правильный способ генерации "матрицы значений", представленной на рисунке выше.Я знаю, что есть и другие способы составления графика тепловой карты без артефактов, например, с использованием plt.matshow(mtx, cmap=plt.cm.jet); plt.show(block=False)
или plt.hist2d(x, y, bins=100)
.Что я спрашиваю, так это где проблема в самой генерации моей матрицы, которая создает эти почти нулевые элементы.