Вот математический способ сделать это. Если любые две пары значений p1, p2 в массиве A «одинаковы, но с фазой», то если c=p1/p2
, то c[0]==c[1]
. Мы можем сделать это векторизованным способом, используя матричное умножение:
import numpy as np
import warnings
warnings.filterwarnings("ignore")
def phasefilter(A):
A_0, A_1 = A[:,0].reshape(-1,1), A[:,1].reshape(-1,1)
B_0, B_1 = 1/(A_0.T), 1/(A_1.T)
C_0, C_1 = A_0@B_0, A_1@B_1
phasemap = C_0==C_1
return np.array([A[i] for i,(pmap) in enumerate(phasemap) if phasemap[i][np.arange(i+1,A.shape[0])].sum()==0])
Я импортировал предупреждения, поскольку при делении двух пар значений мы можем делить на ноль.
A = np.array([[1, 0],[0,1],[1,-1],[-1,1],[1j,1],[1,-1j]])
print('Out:\n',phasefilter(A))
A = np.array([[2,3],[1,2],[-2,-3],[4,-5],[6,7],[-5,4]])
print('Out:\n',phasefilter(A))
A = np.array([[2,3],[1,2],[-2,-3],[4,-5],[2,3],[-5,4]])
print('Out:\n',phasefilter(A))
Вывод:
Out:
[[ 1.+0.j 0.+0.j]
[ 0.+0.j 1.+0.j]
[-1.+0.j 1.+0.j]
[ 1.+0.j -0.-1.j]]
Out:
[[ 1 2]
[-2 -3]
[ 4 -5]
[ 6 7]
[-5 4]]
Out:
[[ 1 2]
[ 4 -5]
[ 2 3]
[-5 4]]
Редактировать: Несмотря на то, что описанный выше метод прост, он плохо масштабируется до больших размеров, поэтому вот еще более обобщенное решение для любого числа измерений:
def phasefilter(A, P=np.array([[1,-1,1j,-1j]])):
N, M = A.shape[0], A.shape[1]
AT = A.reshape(N,M,1)
PM = np.swapaxes(AT@P, 1, 2).reshape(-1,M)
return A[[i for i in range(N) if not (PM[4*i]==PM[4*(i+1):]).all(axis=1).any()]]