Попытка проверить точки внутри круга с помощью Numpy - PullRequest
1 голос
/ 04 апреля 2019

Я новичок в numpy, и передо мной была поставлена ​​следующая задача: мне нужно создать два массива случайных чисел (между 0 + 1). Один числовой массив представляет координаты x, а другой представляет координаты y. Затем мне нужно проверить, попадают ли точки в окружность радиуса один, используя квадратный корень (x ^ 2 + y ^ 2) <1. </p>

В настоящее время я просто пытаюсь выровнять свои массивы и сложить их вместе. То, что, вероятно, очень простая задача, не доставляет мне неприятностей.

import matplotlib.pyplot as plt
import numpy as np

plots = 100

dataOne = np.random.random(size = plots)
dataTwo = np.random.random(size = plots)

circle = plt.Circle((0,0), 1, alpha = 0.1)
plt.gca().add_patch(circle)
plt.xlim(0, 5)
plt.ylim(0, 5)
plt.show()

squareDataOne = dataOne ** 2
squareDataTwo = dataTwo ** 2

if squareDataOne + squareDataTwo < 1:
    print("Now check square-root!")

Я продолжаю получать сообщение об ошибке: Значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any () или a.all (). Кто-нибудь может объяснить, почему Python / Numpy не нравится это? Мне сказали попытаться использовать логическое выражение для нарезки массива. Кто-нибудь может дать предложения о том, как лучше всего включить это в мой код? Любые предложения или советы для новичка приветствуются.

Ответы [ 4 ]

2 голосов
/ 04 апреля 2019

squareDataOne выглядит так:

[7.43871942e-02 2.73007883e-01 5.23115388e-03 6.57541340e-01
 3.08779564e-01 1.24098667e-02 5.08258990e-01 6.52590269e-01
 8.90656103e-02 3.76389212e-02 2.12513661e-01 2.79683875e-01
 7.76233370e-01 6.48353342e-02 8.01663208e-01 8.69331480e-01
 4.34903542e]

squareData2 выглядит аналогично. Выражение в вашем if выражении:

squareDataOne + squareDataTwo < 1

создает этот массив:

[ True False  True  True  True  True  True  True False False  True False
  True False False  True  True  True  True  True False  True False False
  True  True False  True  True  True  True  True  True  True  True  True
  True  True False False  True False]

То есть ваш оператор , если ожидает значение True или False , и получает этот массив. Сообщение об ошибке говорит вам, что Python не знает, как превратить этот массив в одно True или False значение.

Я недостаточно хорошо понимаю логику вашего кода, чтобы знать, что вам нужно сделать, чтобы это исправить. Очевидно, у вас есть много данных, и все же вы ожидаете решить двоичное событие; если вы должны напечатать "Теперь проверьте квадратный корень!" или нет. Понятия не имею, как тебе это сделать.

0 голосов
/ 04 апреля 2019
# Change number of random points to 5.
plots = 5
...
inside_circle = squareDataOne + squareDataTwo < 1
print(inside_circle)

output:
[False  True  True False False]

Это показывает, что inside_circle - это пустой массив типа d "bool", указывающий, находится ли каждая точка внутри окружности, а не одна переменная "bool", поэтому инструкция python if выдает ошибку. Вы можете суммировать все "bool" в inside_circle, чтобы получить количество точек внутри круга (при суммировании массива bool numpy обрабатывает True как 1 и False как 0).

plots = 100
...
num_inside = np.sum(inside_circle)
# Check if all points are inside.
if num_inside == plots:
    print('All inside.')

# If what you really want to achieve is to estimate the area of one quarter of a circle
# using Monte Carlo Sampling.
print(num_inside / plots)    # Your estimate.
print(np.pi / 4)             # Actual area.

output:
0.79
0.7853981633974483

Оценка близка, верно?

0 голосов
/ 04 апреля 2019

Я думаю, вы хотите заменить это:

if squareDataOne + squareDataTwo < 1:
    print("Now check square-root!")

на что-то вроде:

# Calculate radii
radii = (squareDataOne + squareDataTwo)**0.5

# Create a boolean array (True/False values) for filtering
incircle = radii < 1

# Print the number of points inside the circle (Python 3.6+ for the f-string)
print(f"There are {np.sum(incircle)} points inside the circle")

# Plot the points within the circle
plt.scatter(dataOne[incircle], dataTwo[incircle])

dataOne[incircle] и dataTwo[incircle] будут извлекать только эти элементы (т.е. [x, y] пары координат) из каждого массива, где значение incircle равно True.

0 голосов
/ 04 апреля 2019

Затем мне нужно проверить, попадают ли точки в круг радиус один, используя квадратный корень (x ^ 2 + y ^ 2) <1. </p>

Вы можете использовать фильтрацию массива

pt_norm = (squareDataOne + squareDataTwo)
r_inside_circle = np.sqrt(pt_norm[pt_norm < 1])

Это даст вам радиус всех точек, которые попадают в круг в r_inside_circle. При увеличении значения plots вы увидите, что (4.0*len(r_inside_circle))/len(dataOne) приблизится к PI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...