给定一个矩阵,return 它所有成对邻居的列表(或生成器)
Given a matrix, return a list (or generator) of all it's pairwise-neighbors
假设我有这个矩阵:(不必平方)
a b c
d e f
g h i
我想要 return 一个包含所有成对邻居的列表或生成器。
含义:
[[a,b], [b,c], [d,e], [e,f], [g,h], [h,i], [a,d], [b,e], [c,f], [d,g], [e,h], [f,i]]
AND(!) 仅向 return 添加一个选项:a*b + b*c + d*e + e*f + g*h + ... + f*i
如果示例中的解释不够清楚,如果两个元素彼此相邻,从左到右或从下到上(不是对角线!)。
这是我目前所做的:
def neighbors(X, returnSet=False):
'''
:param X: The matrix
:param returnSet: False[DEFAULT] = Return sum of Xi*Xj (when Xi and Xj are pairwise-neighbors)
True = Return the set of all neighbors.
:return: Depends on returnSet
'''
sum, neighbors = 0, []
for i in range(0, X.shape[0]):
for j in range(0, X.shape[1]):
if j + 1 < X.shape[1]:
neighbors.append([X[i][j], X[i][j + 1]]) if returnSet else None
sum += X[i][j] * X[i][j + 1]
if i + 1 < X.shape[0]:
neighbors.append([X[i][j], X[i + 1][j]]) if returnSet else None
sum += X[i][j] * X[i + 1][j]
return neighbors if returnSet else sum
此代码有效,但我不太喜欢它的外观。你能想出比这更“酷”的算法吗?或者更有效率?我喜欢 python 代码简短。
与您的 基本相同,只是在两个轴上使用双点积(不是那么漂亮)。
a = np.arange(9).reshape(3,3)
np.einsum('ij, ij->', a[1:], a[:-1]) + np.einsum('ij, ij->', a[:, 1:], a[:, :-1])
Out[]: 232
neighbors(a)
Out[]: 232
如果你只想要一对:
h = np.stack([a[:, 1:], a[:, :-1]]).transpose(1,2,0).reshape(-1, 2)
v = np.stack([a[1:], a[:-1]]).transpose(1,2,0).reshape(-1, 2)
np.vstack([h, v])
Out[]:
array([[1, 0],
[2, 1],
[4, 3],
[5, 4],
[7, 6],
[8, 7],
[3, 0],
[4, 1],
[5, 2],
[6, 3],
[7, 4],
[8, 5]])
假设我有这个矩阵:(不必平方)
a b c
d e f
g h i
我想要 return 一个包含所有成对邻居的列表或生成器。 含义:
[[a,b], [b,c], [d,e], [e,f], [g,h], [h,i], [a,d], [b,e], [c,f], [d,g], [e,h], [f,i]]
AND(!) 仅向 return 添加一个选项:a*b + b*c + d*e + e*f + g*h + ... + f*i
如果示例中的解释不够清楚,如果两个元素彼此相邻,从左到右或从下到上(不是对角线!)。
这是我目前所做的:
def neighbors(X, returnSet=False):
'''
:param X: The matrix
:param returnSet: False[DEFAULT] = Return sum of Xi*Xj (when Xi and Xj are pairwise-neighbors)
True = Return the set of all neighbors.
:return: Depends on returnSet
'''
sum, neighbors = 0, []
for i in range(0, X.shape[0]):
for j in range(0, X.shape[1]):
if j + 1 < X.shape[1]:
neighbors.append([X[i][j], X[i][j + 1]]) if returnSet else None
sum += X[i][j] * X[i][j + 1]
if i + 1 < X.shape[0]:
neighbors.append([X[i][j], X[i + 1][j]]) if returnSet else None
sum += X[i][j] * X[i + 1][j]
return neighbors if returnSet else sum
此代码有效,但我不太喜欢它的外观。你能想出比这更“酷”的算法吗?或者更有效率?我喜欢 python 代码简短。
与您的
a = np.arange(9).reshape(3,3)
np.einsum('ij, ij->', a[1:], a[:-1]) + np.einsum('ij, ij->', a[:, 1:], a[:, :-1])
Out[]: 232
neighbors(a)
Out[]: 232
如果你只想要一对:
h = np.stack([a[:, 1:], a[:, :-1]]).transpose(1,2,0).reshape(-1, 2)
v = np.stack([a[1:], a[:-1]]).transpose(1,2,0).reshape(-1, 2)
np.vstack([h, v])
Out[]:
array([[1, 0],
[2, 1],
[4, 3],
[5, 4],
[7, 6],
[8, 7],
[3, 0],
[4, 1],
[5, 2],
[6, 3],
[7, 4],
[8, 5]])