【问题标题】:Set values around a specific position in a 2D array using Python使用 Python 在二维数组中的特定位置周围设置值
【发布时间】:2022-01-08 14:16:24
【问题描述】:

假设我有一个二维数组,例如:

[
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 3, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]

我想将 3 周围的所有值 2 级别设置为特定数字,例如:

[
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 0, 1, 1, 3, 1, 1, 0],
    [0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]

请注意,3 可以在列表中的任何位置,我正在使用随机生成器来获取它。那么我怎么能做到这一点呢?也许使用 for 循环?

【问题讨论】:

  • 是 3 变量还是严格来说总是 3?
  • 还有行和列
  • 你使用的是 numpy 还是基础 python 中的严格列表?
  • 设置了3,但是它的位置可以移动。而且我目前没有使用 numpy,但如果它更容易的话,我可以使用。

标签: python list multidimensional-array


【解决方案1】:

继续评论 - 我发现 numpy 对于这样的切片非常有用;

import numpy as np

arr = np.array([
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 3, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
])

xs, ys = np.where(arr == 3)
arr[xs[0] - 2: xs[0] + 3, ys[0] - 2: ys[0] + 3] = 1
arr[xs[0], ys[0]] = 3

显然也可以采用纯 python/列表形式,但你可能会在双迭代中陷入困境

【讨论】:

  • 您能解释一下这是如何工作的吗?
  • where 返回数组等于 3 的位置,在您的情况下,这只是一个位置,因此使用 xs[0]ys[0] 来识别这一点。下一行使用切片符号numpy.org/doc/stable/user/basics.indexing.html 将 3 到 1 周围的 5x5 网格设置为 1(包括 3 位置)(因此我对 numpy 的评论)。最后一行只是将 3 位置设置回 3
  • 有没有办法在外面创建一个'2'的边框?
  • arr[[0, -1]] = 2 arr[:, [0, -1]] = 2
  • 谢谢,我会检查一下我得到了什么。
【解决方案2】:

这是一个纯 Python 方法(虽然比较笨拙):

A = [
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 3, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]

for j, a in enumerate(A):
    try:
        i = a.index(3)
        P = A[j-1] if j > 0 else None
        Q = A[j+1] if j < len(a) - 1 else None
        for k in range(max(0, i-2), min(i+3, len(a))):
            if P:
                P[k] = 1
            if Q:
                Q[k] = 1
            a[k] = 1
        a[i] = 3
        break
    except ValueError:
        pass
print(A)

【讨论】:

  • 试一试的建议,但这就是我所说的双迭代中膝盖深处的意思。
  • @Helios 我不同意你的观点。我只是想在没有其他模块的帮助下实现一些东西。我已经稍微缩写了
  • 试过以下版本
【解决方案3】:

纯蟒蛇

A = [
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 3, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]


location = [(i, j) for i, row in enumerate(A) for j, item in enumerate(row) if item == 3][0]
for i, row in enumerate(A):
    for j, item in enumerate(row):
        if (abs(i - location[0]) <= 2) and (abs(j - location[1]) <= 2) and not ((i, j) == location):
            A[i][j] = 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 2020-02-14
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多