[英]Converting 2D array into [ [ x0 y0 ] [x1 y1] [x2 y2] ] form
[英]Mapping z's in numpy array A = [[x0, y0, z0], [x1, y1, z1]] for 3rd column of array B = [[x1, y1, ?], [x0, y0, ?]] based off matching (x,y)?
我有一個 numpy 數組T
其行具有以下列結構: [x, y, value]
,其中 x, y, value 是整數。 示例T
數組如下所示:
[[1, 0, 4],
[0, 2, 3],
[1, 2, 7]]
此數據來自 model ,其中第三列指定元組(x, y)
的變量值。 在 model 中,此元組對應於值的 label。 例如,我的 label T_10
(下標10
)的值為4
, T_02
的值為3
, T_12
的值為7
。
現在,我想交換一對標簽。 例如,我想將所有標簽2
替換為1
(反之亦然),以分別獲得前面示例的T_20
、 T_01
和T_21
。 所以,這個新數據是
U = [[2, 0, ?],
[0, 1, ?],
[2, 1, ?]]
我的問題是我不知道如何使我的新數據看起來像這樣:
U = [[2, 0, -3]
[0, 1, -4],
[2, 1, -7]]
這個新數據應該遵循兩個規則:
首先,它應該正確識別T
的第一列和第二列(x, y)
) 與U
中的新(x, y)
相同的行。 對於U
的每一行,如果T
的有序對(x, y) = (x, y)
,則適當的 '?' U
的第三列中的值應該是T
中的對應值。
第二:另一方面,如果(x, y)
of U = (y, x)
of T
,那么它應該是相應value
的負數。
我的嘗試涉及首先提取T
的列,然后使用以下 function 交換這對標簽:
def swap_indices(a, pair):
for n, i in enumerate(a):
if i == pair[0]: # check whether a0's element is = swap element 1
a[n] = pair[1]
elif i == pair[1]:
a[n] = pair[0]
return a
例如,我會將 label 0
與1
交換,反之亦然,用於x
列和y
列,使用:
pair = (0, 1)
a0 = swap_indices(T[:,0], pair) # column x
a1 = swap_indices(T[:,1], pair) # column y
然后我遍歷T
的行數; num_rows_of_T
:
for k in range(num_rows_of_T):
temp = np.where((T[k, 0] == a0[k]) & (T[k, 1] == a1[k]) | ((T[k, 0] == a1[k]) & (T[k, 1] == a0[k])))
上面,我試圖獲取(x, y)
of U
= (x, y)
of T
或(x, y)
of U = (y, x)
of T
的行的索引。 然而,這是我卡住的地方。 我不認為以上是正確的。 此外,這種方法不會讓我應用第二條規則,即如果(x, y) = (y, x)
取T
值的負數。 我還嘗試使用set()
作為初學者(以獲得無序對),但即使在那時我也無法正確找到T
的相應值。
基本上,我想找到與U
中的新標簽匹配的T
value
s 。 我的數據很好,因為可能只存在一組可能的坐標,並且T
和U
的(x,y)
之間總是存在雙射映射(給定我的兩個規則)。
有什么建議嗎? 請根據需要幫助編輯問題。 我很難問。
這是一個最小的工作示例:
import numpy as np
# swap index labels if match swap pair
def swap_indices(a, pair):
for n, i in enumerate(a):
if i == pair[0]: # check whether a0's element is = swap element 1
a[n] = pair[1]
elif i == pair[1]:
a[n] = pair[0]
return a
def find_valid_swaps(The1 = np.array([1, 0, -1, 1, 0, 1]), headers = np.array(['10', '20', '21', '30', '31', '32'])):
num_indices = len(The1)
T = np.zeros((num_indices,3)); U = T;
# match format given for T in question
for i in range(num_indices):
T[i,:] = [int(list(headers[i])[0]), int(list(headers[i])[1]), The1[i]]
pair = (0, 1) # label pair to swap
a0 = swap_indices(T[:, 0], pair) # column 0 of U
a1 = swap_indices(T[:, 1], pair) # column 1 of U
# try to extract correct 'value' from T based on new labels in U
for k in range(num_indices):
temp = np.where((T[k, 0] == a0[k]) & (T[k, 1] == a1[k]) | ((T[k, 0] == a1[k]) & (T[k, 1] == a0[k])))
print("temp",temp[0][0])
U[k, :] = [a0[k], a1[k], T[temp[0][0], 2]] # here, I would finally create the new U matrix, applying both rules
print(U)
find_valid_swaps()
使用@MadPhysicist 的答案的更多相關示例:
# swap index labels if match swap pair
def swap_indices(a, pair):
for n, i in enumerate(a):
if i == pair[0]: # check whether a0's element is = swap element 1
a[n] = pair[1]
elif i == pair[1]:
a[n] = pair[0]
return a
def key(arr, m):
return arr[:, 0] * m + arr[:, 1]
def find_valid_swaps(Thetas1 = np.array([1, 1, 0, 0, -1, -1]), Thetas2 = np.array([1, 0, -1, 1, 0, 1]), num_bands = 4, headers = np.array(['10', '20', '21', '30', '31', '32'])):
import itertools # for permutations: https://stackoverflow.com/questions/40092474/get-all-pairwise-combinations-from-a-list
if (Thetas1==Thetas2).all():
print("Warning: Input sets of indices are equal to each other. Will check other possible permutations regardless.")
else:
print("Input sets of indices are unique. Will proceed checking other viable permutations.")
num_indices = len(Thetas1)
T = np.zeros((num_indices,3))
U = np.zeros((num_indices,3))
for i in range(num_indices):
T[i,:] = [int(list(headers[i])[0]), int(list(headers[i])[1]), Thetas2[i]]
print("input T")
print(T)
pair = (2,3)
a0 = swap_indices(T[:,0], pair) # column 1
a1 = swap_indices(T[:,1], pair) # column 2
for k in range(num_indices):
U[k, :] = [a0[k], a1[k], 0]
# below code due to @MadPhysicist from https://stackoverflow.com/questions/67223782/mapping-zs-in-numpy-array-a-x0-y0-z0-x1-y1-z1-for-3rd-column-of-ar/67235030?noredirect=1#67235030
y_max = T[:, 1].max() + 1
Tkey = key(T, y_max)
s = np.argsort(Tkey)
Ukey = key(U, y_max)
i = np.searchsorted(Tkey, Ukey, sorter=s)
i[i == len(i)] -= 1 # cleanup indices that won't match anyway
mask = (Ukey == Tkey[s[i]])
U2key = key(U[~mask, 1::-1], y_max)
j = np.searchsorted(Tkey, U2key, sorter=s)
U[mask, -1] = T[s[i[mask]], -1]
U[~mask, -1] = -T[s[j], -1]
print("reordered U")
print(U)
以上給出了output:
input T
[[ 1., 0., 1.]
[ 2., 0., 0.]
[ 2., 1., -1.]
[ 3., 0., 1.]
[ 3., 1., 0.]
[ 3., 2., 1.]]
reordered U
[[ 1., 0., 1.]
[ 3., 0., 0.]
[ 3., 1., -1.]
[ 2., 0., 1.]
[ 2., 1., 0.]
[ 2., 3., 1.]]
您可以將算法歸結為三個大步驟:
組合結果顯然是微不足道的。 整個操作在O(N log N)
時間內應該是完全可行的,因為這就是每一步需要多長時間。
由於np.searchsorted
是第 2 步和第 3 步的主要候選者,假設您可以將前兩列轉換為唯一鍵。 例如,假設在所有情況下y <= y_max
,並且y_max
有一個合理的界限,使得x * y_max + y <= 2**32-1
對於所有x
。 您可以在閑暇時使用np.int64
或使用x_max
而不是y_max
。
所以現在你做:
def key(arr, m):
return arr[:, 0] * m + arr[:, 1]
y_max = T[:, :1].max(None) + 1
Tkey = key(T, y_max)
s = np.argsort(Tkey)
要查找U
的哪些元素匹配:
Ukey = key(U, y_max)
i = np.searchsorted(Tkey, Ukey, sorter=s)
i[i == len(i)] -= 1 # cleanup indices that won't match anyway
mask = (Ukey == Tkey[s[i]])
現在找到反向索引。
U2key = key(U[~mask, 1::-1], y_max)
j = np.searchsorted(Tkey, U2key, sorter=s)
由於映射是雙射的,所以這一步只搜索保證存在的元素,不需要驗證索引。
現在您可以組合索引。 如果U
還沒有第三列,請添加一列:
U = np.concatenate((U, np.empty_like(T[:, :1])), axis=1)
使用我們計算的索引,提取您想要的Tsort
元素:
U[mask, -1] = T[s[i[mask]], -1]
U[~mask, -1] = -T[s[j], -1]
現在,如果您無法獲得像key
工作這樣的映射,事情可能會更復雜一些。 如果沒有其他方法,請先嘗試
def key(arr):
return arr[:, 0] + 1j * arr[:, 1]
復雜值將僅用作排序鍵,僅用作排序鍵。 如果失敗,您可能必須定義結構化數據類型並通過它查看您的數組以使搜索正常工作。 您當然可以實現分層搜索,但我覺得這超出了 scope 的范圍。
這是一個基於您的T
的完整玩具示例,稍微修改了U
,在最后一列中顯示正數和負數:
>>> T = np.array([[1, 0, 4],
[0, 2, 3],
[1, 2, 7]])
>>> U = np.array([[2, 1, 0],
[1, 0, 0],
[2, 0, 0]])
>>> def key(arr, m):
... return arr[:, 0] * m + arr[:, 1]
>>> y_max = T[:, :1].max(None) + 1
>>> Tkey = key(T, y_max)
>>> s = np.argsort(Tkey)
>>> Ukey = key(U, y_max)
>>> i = np.searchsorted(Tkey, Ukey, sorter=s)
>>> i[i == len(i)] -= 1 # cleanup indices that won't match anyway
>>> mask = (Ukey == Tkey[s[i]])
>>> U2key = key(U[~mask, 1::-1], y_max)
>>> j = np.searchsorted(Tkey, U2key, sorter=s)
>>> U[mask, -1] = T[s[i[mask]], -1]
>>> U[~mask, -1] = -T[s[j], -1]
>>> print(U)
[[ 2 1 -7]
[ 1 0 4]
[ 2 0 -3]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.