2016-04-22 4 views
1

I jst начал использовать numpy на этой неделе и очень смущен этим. кажется очень отличным от обычных функций python.Я использую массив numpy произвольно сгенерированных упорядоченных пар, мне нужно определить, являются ли упорядоченные пары разными типами треугольников

С массивом, размером 1000X6, есть способ пойти по строке в массиве и проверить, например, равносторонний треугольник. У меня есть 6 столбцов, так что в каждой строке есть троек, 2 целых числа для каждой точки ,

import numpy as np 
pnts = np.random.randint(0,50,(1000, 6)) 

Я также подумал, что может быть лучше, чтобы создать 3 массивы, которые, как это:

import numpy as np 
A = np.random.random((10,2)) 
B = np.random.random((10,2)) 
C = np.random.random((10,2)) 

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

Есть ли лучший способ создать массив, который представляет 1000 тройки упорядоченных пар и как я могу найти треугольники в этом массиве, например, равносторонний треугольник.

Я внесла некоторые изменения сейчас. Я создал два массива для координат x и y координат.

x = np.random.randint(0,10,(3,1000)) 
y = np.random.randint(0,10,(3,1000)) 

############# Добавление к вопросу #############

У меня есть алгоритмы, которые принимают каждый соответствующий х и y координаты, которые находят там длину и углы для каждого треугольника. Я бы опубликовал, но его слишком много кода. А также теперь у меня есть функции, которые используют углы и длины сторон, чтобы найти Scalene, Equilateral, Right Isoceles и Non-right Isoceles.

Мой вопрос теперь более связан с индексом. В качестве примера я буду использовать равносторонний треугольник, потому что именно с этим мы работаем.

E = np.column_stack((ACXY,ABXY,CBXY)) 
ES = np.logical_and(E[:,0] == E[:,1], E[:,1] == E[:,2]) 

У меня есть это, чтобы найти равносторонние треугольники.

- ACXY = the distance from point A to C 
- ABXY = the distance from point A to B 
- CBXY = the distance from point C to B 

Я хочу, чтобы иметь возможность принимать все координатные тройки, которые являются равносторонними треугольниками, индексировать их и поместить их в новый массив под названием E_Tri. Я не думаю, что мне нужна функция, создающая логические значения. Я подумал, что, возможно, If: else: утверждения, возможно, лучший способ сделать это.

Также это может помочь, я покажу E = np.column_stack((ACXY,ABXY,CBXY)) , чтобы помочь понять массив (E).

[[ 4.   4.47213595 7.21110255] 
[ 3.60555128 2.23606798 5.83095189] 
[ 2.23606798 9.05538514 8.54400375] 
..., 
[ 3.60555128 9.05538514 6.08276253] 
[ 8.94427191 8.54400375 1.  ] 
[ 10.63014581 1.   10.  ]] 

E будет выглядеть так. Надеюсь, это будет иметь смысл, если не сообщите мне.

Возможно, что-то подобное, хотя это не будет работать, просто добавив к вопросу.

E = np.column_stack((ACXY,ABXY,CBXY)) 
equilateral = [] 
def E_Tri(E): 
    if E[:,0] == E[:,1] and E[:,1] == E[:,2]: 
     equilateral.append(E_Tri) 
    else: 
     return E 
+0

Если вы хотите увидеть алгоритмы я использовал, чтобы получить (ACXY, ABXY, CBXY) дайте мне знать, и я постараюсь, чтобы очистить их и размещать ITSO его читабельны и менее продолжительны. – LizardWizard

ответ

3

Вы хорошо описали, как вы храните данные, но не алгоритм. Например, если мы хотим ответить на вопрос «Является ли этот набор из трех (x, y) точек P1 ..P3 равносторонний треугольник», мы можем сформулировать это так:

dist(P1,P2) == dist(P2,P3) == dist(P3,P1) 

Где dist(P1,P2) использует теорему Пифагора:

sqrt((P1.x - P2.x)**2 + (P1.y - P2.y)**2) 

Но обратите внимание, что sqrt() ненужно, потому что все, что мы заботимся о том, если все три ноги (и если они равны, их квадраты также будут равны).

В NumPy мы хотим сделать все параллельно. Поэтому, если у вас есть массив 1000x6, представляющий 1000 треугольников, вам нужно сделать все Операция ns на 1000 элементов за раз. Если массив называется А и его столбцы:

P1.x, P1.y, P2.x, P2.y, P3.x, P3.y 

Тогда первые операции:

A[0] - A[2] # P1.x - P2.x 
A[1] - A[3] # P1.y - P2.y 
A[2] - A[4] 
A[3] - A[5] 
A[4] - A[0] 
A[5] - A[1] 

Что может быть более лаконично написано:

R = A - np.roll(A, -2, axis=0) # 1000x6 array of all differences 

Это делается, вам может квадратировать все эти результаты 1000x6 сразу, давая нам массив 1000x6 R, из которого мы добавляем пары x и y, чтобы получить квадраты расстояний:

R[0] + R[1] # (P1.x - P2.x)**2 + (P1.y - P2.y)**2 
R[2] + R[3] 
R[4] + R[5] 

Что сказать:

S = R[0::2] + R[1::2] # three column-wise additions at once 

Это дает нам 1000x3 квадратики-на-расстояниями массив S. Теперь мы просто проверить для каждой строки, если ее столбцы все равны:

np.logical_and(S[0] == S[1], S[1] == S[2]) 

Это дает нам булевый вектор 1000x1, который говорит нам, если каждая строка является равносторонним треугольником.

Обратите внимание, что мы никогда не выходили по очереди в итеративном режиме. Это связано с тем, что делать это в NumPy намного медленнее, чем выполнять операции с столбцами.

Обратите внимание, что я написал выше, предполагая, что форма массивов на самом деле (6,1000), когда я говорю 1000x6. Это для удобства обозначений (A[0] вместо A[:,0]), а также потому, что оно более эффективно, когда мы работаем с столбцами, поскольку NumPy по умолчанию использует порядок строк. Вы можете указать np.transpose() свои входные данные.

Таким образом, в конце концов, это просто:

A = pnts.T 
R = np.square(A - np.roll(A, -2, axis=0)) 
S = R[0::2] + R[1::2] # 1000x3 squares of distances 
np.logical_and(S[0] == S[1], S[1] == S[2]) # 1000 True/False results 
+0

хорошее объяснение; но было бы еще чище, если бы А имел форму (1000, 3, 2) –

+0

@EelcoHoogendoorn: достаточно хорошо; Я просто решил придерживаться формы, указанной в OP, но 'reshape()' в начале не повредит. Я оставлю это как упражнение для читателя! –

+0

Благодарим за помощь! У резонанса у меня 6 чисел, потому что они упорядоченные пары. Я хотел иметь массивы упорядоченных пар для разных типов треугольников, таких как равносторонний, правый, scalene, e.t.c .. затем складывая эти массивы вместе в конце (vstack). Если бы я начал с формы (10000, 3, 2), было бы легче (np.roll) и (points.repeat) создать новый массив упорядоченных пар, начиная с 3x2? также кто-нибудь сможет объяснить (уникальную) функцию в numpy? – LizardWizard