如何确定一维数组中的相邻元素?
How to determine neighboring elements from a 1D array?
我正在研究有限元分析代码,我目前有一个一维数组,其中列出了元素密度值,如下所示:
x = np.ones(12) 其中索引是元素编号 0, 1, 2, ..., 10, 11
绘制时的元素是这样的:
0 - 3 - 6 - 9
1 - 4 - 7 - 10
2 - 5 - 8 - 11
我设置了 x 和 y 方向的元素数量(对于这种情况,x 方向为 4,y 方向为 3)但是我很难确定环绕元素。我需要找到一种方法来确定给定元素周围的 3、5 或 8 个元素。例如,如果 I select 元素 0 周围的元素是 1、3、4 或者如果 I select 元素 6 周围的元素是 3、4、7、9、10 或者如果 I select 元素 7 环绕元素为 3, 4, 5, 6, 8, 9, 10, 11...
这里的最终目标是放入一个半径,并根据它确定 selected 元素周围的元素编号。任何建议或帮助将不胜感激。出于某种原因,我无法确定在 python.
中执行此操作的逻辑
determine the logic to do this
- 具有 6 个项目的一维数组具有索引 -
[0,1,2,3,4,5]
- 建议的形状是 2 行和 3 列 -
M,N = 2,3
。
- 对于任何项目的索引 (
i
),其行和列是 c,r = divmod(i,M)
- 相邻的列、行索引将是
-
cplus,cminus = c + 1, c - 1
rplus, rminus = r + 1, r - 1
cplus,r
cminus,r
c,rplus
c,rminus
cplus,rplus
cplus,rminus
cminus,rplus
cminus,rminus
- 需要使用
(col * M) + row
将这些二维索引转换为一维索引
例如
[0,1,2,3,4,5]
M,N = 2,3
'''
0 2 4
1 3 5
'''
项目 4 的二维索引是 c,r = divmod(4,M)
--> (2,0)
(col,row)
其邻居的二维索引之一是 c,rplus
--> (2,1)
那个邻居的 1d 索引是 (2 * M) + 1
--> 5
将邻居的二维索引转换为一维索引后,您需要检查并丢弃一些没有意义的索引。
- 项目 4 在 右上角 的一个角落,没有像
c,rminus
这样的邻居 (2,-1)
感觉。或者 cplus,r
... (3,0)
这也没有意义。
警告 - 我没有尝试彻底测试它。
这是一个 returns 可调用的函数。
import operator
def get_neighbors(index, shape=(M,N)):
'''Returns a callable.
(M,N) --> (number_of_rows, number_of_columns)
'''
M, N = shape
# 2d index
c, r = divmod(index, M)
print(f'2d index: {(c,r)}')
# neighbors
cplus, cminus = c + 1, c - 1
rplus, rminus = r + 1, r - 1
# dot product of (c,cplus,cminus) and (r,rplus,rminus)?
neighbors = [
(cminus, rminus),
(cminus, r),
(cminus, rplus),
(c, rplus),
(cplus, rplus),
(cplus, r),
(cplus, rminus),
(c, rminus),
]
# print(neighbors)
# validate/filter
neighbors = [
(col, row) for col, row in neighbors if (0 <= col < N) and (0 <= row < M)
]
# print(neighbors)
# 1d indices
one_d = [(col * M) + row for col,row in neighbors]
# print(one_d)
return operator.itemgetter(*one_d)
试试吧。
>>> a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't']
>>> M,N = 4,5 # nrows, ncols
'''
[['a' 'e' 'i' 'm' 'q']
['b' 'f' 'j' 'n' 'r']
['c' 'g' 'k' 'o' 's']
['d' 'h' 'l' 'p' 't']]
'''
>>> # i's neighbors
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (2, 0)
>>> q(a)
('e', 'f', 'j', 'n', 'm')
>>>
>>> # k's neighbors
>>> q = get_neighbors(a.index('k'),(M,N))
2d index: (2, 2)
>>> q(a)
('f', 'g', 'h', 'l', 'p', 'o', 'n', 'j')
>>>
>>> # q's neighbors
>>> q = get_neighbors(a.index('q'),(M,N))
2d index: (4, 0)
>>> q(a)
('m', 'n', 'r')
>>>
i
不同形状的邻居
>>> M,N = 5,4
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (1, 3)
>>> q(a)
('c', 'd', 'e', 'j', 'o', 'n', 'm', 'h')
>>> M,N = 10,2
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (0, 8)
>>> q(a)
('j', 't', 's', 'r', 'h')
>>> M,N = 2,10
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (4, 0)
>>> q(a)
('g', 'h', 'j', 'l', 'k')
>>>
Numpy 文档中有一个很好的讨论,关于 making/treating 1d 事物作为 Nd 事物 - Internal memory layout of an ndarray
您描述 1d --> 2d 转换的方式使用了列主要方案。我习惯于思考 row-major - 我将函数写到 accept/expect a (nrows,ncols) shape
参数但在函数内部我有点切换到栏目主要处理。我不得不 小心 所以也许这是一个糟糕的设计。
我正在研究有限元分析代码,我目前有一个一维数组,其中列出了元素密度值,如下所示:
x = np.ones(12) 其中索引是元素编号 0, 1, 2, ..., 10, 11
绘制时的元素是这样的:
0 - 3 - 6 - 9
1 - 4 - 7 - 10
2 - 5 - 8 - 11
我设置了 x 和 y 方向的元素数量(对于这种情况,x 方向为 4,y 方向为 3)但是我很难确定环绕元素。我需要找到一种方法来确定给定元素周围的 3、5 或 8 个元素。例如,如果 I select 元素 0 周围的元素是 1、3、4 或者如果 I select 元素 6 周围的元素是 3、4、7、9、10 或者如果 I select 元素 7 环绕元素为 3, 4, 5, 6, 8, 9, 10, 11...
这里的最终目标是放入一个半径,并根据它确定 selected 元素周围的元素编号。任何建议或帮助将不胜感激。出于某种原因,我无法确定在 python.
determine the logic to do this
- 具有 6 个项目的一维数组具有索引 -
[0,1,2,3,4,5]
- 建议的形状是 2 行和 3 列 -
M,N = 2,3
。 - 对于任何项目的索引 (
i
),其行和列是c,r = divmod(i,M)
- 相邻的列、行索引将是
-
cplus,cminus = c + 1, c - 1 rplus, rminus = r + 1, r - 1 cplus,r cminus,r c,rplus c,rminus cplus,rplus cplus,rminus cminus,rplus cminus,rminus
-
- 需要使用
(col * M) + row
将这些二维索引转换为一维索引
例如
[0,1,2,3,4,5]
M,N = 2,3
'''
0 2 4
1 3 5
'''
项目 4 的二维索引是
c,r = divmod(4,M)
-->(2,0)
(col,row)其邻居的二维索引之一是
c,rplus
-->(2,1)
那个邻居的 1d 索引是
(2 * M) + 1
-->5
将邻居的二维索引转换为一维索引后,您需要检查并丢弃一些没有意义的索引。
- 项目 4 在 右上角 的一个角落,没有像
c,rminus
这样的邻居(2,-1)
感觉。或者cplus,r
...(3,0)
这也没有意义。
- 项目 4 在 右上角 的一个角落,没有像
警告 - 我没有尝试彻底测试它。
这是一个 returns 可调用的函数。
import operator
def get_neighbors(index, shape=(M,N)):
'''Returns a callable.
(M,N) --> (number_of_rows, number_of_columns)
'''
M, N = shape
# 2d index
c, r = divmod(index, M)
print(f'2d index: {(c,r)}')
# neighbors
cplus, cminus = c + 1, c - 1
rplus, rminus = r + 1, r - 1
# dot product of (c,cplus,cminus) and (r,rplus,rminus)?
neighbors = [
(cminus, rminus),
(cminus, r),
(cminus, rplus),
(c, rplus),
(cplus, rplus),
(cplus, r),
(cplus, rminus),
(c, rminus),
]
# print(neighbors)
# validate/filter
neighbors = [
(col, row) for col, row in neighbors if (0 <= col < N) and (0 <= row < M)
]
# print(neighbors)
# 1d indices
one_d = [(col * M) + row for col,row in neighbors]
# print(one_d)
return operator.itemgetter(*one_d)
试试吧。
>>> a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't']
>>> M,N = 4,5 # nrows, ncols
'''
[['a' 'e' 'i' 'm' 'q']
['b' 'f' 'j' 'n' 'r']
['c' 'g' 'k' 'o' 's']
['d' 'h' 'l' 'p' 't']]
'''
>>> # i's neighbors
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (2, 0)
>>> q(a)
('e', 'f', 'j', 'n', 'm')
>>>
>>> # k's neighbors
>>> q = get_neighbors(a.index('k'),(M,N))
2d index: (2, 2)
>>> q(a)
('f', 'g', 'h', 'l', 'p', 'o', 'n', 'j')
>>>
>>> # q's neighbors
>>> q = get_neighbors(a.index('q'),(M,N))
2d index: (4, 0)
>>> q(a)
('m', 'n', 'r')
>>>
i
不同形状的邻居
>>> M,N = 5,4
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (1, 3)
>>> q(a)
('c', 'd', 'e', 'j', 'o', 'n', 'm', 'h')
>>> M,N = 10,2
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (0, 8)
>>> q(a)
('j', 't', 's', 'r', 'h')
>>> M,N = 2,10
>>> q = get_neighbors(a.index('i'),(M,N))
2d index: (4, 0)
>>> q(a)
('g', 'h', 'j', 'l', 'k')
>>>
Numpy 文档中有一个很好的讨论,关于 making/treating 1d 事物作为 Nd 事物 - Internal memory layout of an ndarray
您描述 1d --> 2d 转换的方式使用了列主要方案。我习惯于思考 row-major - 我将函数写到 accept/expect a (nrows,ncols) shape
参数但在函数内部我有点切换到栏目主要处理。我不得不 小心 所以也许这是一个糟糕的设计。