【发布时间】:2021-04-23 03:52:46
【问题描述】:
我有一个 numpy 数组 T,其行具有以下列结构:[x, y, value],其中 x、y、值是整数。示例 T 数组如下所示:
[[1, 0, 4],
[0, 2, 3],
[1, 2, 7]]
此数据来自模型,其中第三列指定元组 (x, y) 的变量值。在模型中,这个元组对应于值的标签。例如,我的标签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 的每一行,如果(x, y) = (x, y) 和T 的有序对,那么适当的'?' U第三列的值应该是T的对应值。
第二:另一方面,如果(x, y) 和U = (y, x) 和T,那么它应该是对应的value 的负数。
我的尝试涉及首先提取T 的列,然后使用以下函数交换这对标签:
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
例如,我将标签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) 的U = (x, y) 的T 或(x, y) 的U = (y, x) 的T 的行的索引。然而,这是我卡住的地方。我不认为以上是正确的。此外,这种方法不会让我应用 第二条规则,如果 (x, y) = (y, x) 取负值,则为 T。我也尝试使用set() 作为初学者(以获得无序对),但即使那样我也无法正确找到T 的相应值。
基本上,我想找到与U 中的新标签匹配的T 的values。我的数据很好,因为可能只存在一组可能的坐标,并且T 的(x,y) 和U 之间总是存在双射映射(给定我的两条规则)。
有什么建议吗? 请根据需要帮助编辑问题。我很难问。
这是一个最小的工作示例:
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)
上面给出了输出:
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.]]
【问题讨论】:
-
SO 不支持 tex 格式。如果必须,请格式化为代码并使用类似 python 的伪代码。
-
这个问题很清楚。
-
我猜你已经有了
T和U的前两列,并且只想在T中搜索行U以找到相应的行。我说的对吗? -
感谢您的建议。我已经相应地编辑了这个问题并提供了一个最小的工作示例。 @swag2198 是的,你是对的。这样的搜索将只产生一个直接查找(直到应用第二条规则)。
-
您可以在示例数组中添加逗号吗?
标签: python arrays numpy indexing label