【问题标题】:How can I shorten this 2D array code?如何缩短此二维数组代码?
【发布时间】:2018-08-28 17:10:28
【问题描述】:

我有以下 sn-p 可以正常工作。

P=im1.copy()
for i in range(P.shape[0]):
    for j in range(P.shape[1]):
        if (n_dens.data[i][j]==-5000 or T_k.data[i][j]==-5000):
            P.data[i][j]=-5000
        else :
            P.data[i][j]=n_dens.data[i][j]*T_k.data[i][j]

P 是一个二维数组。

我想知道如何将其精简为以下几行:

P.data=n_dens.data*T_k.data
P.data=[foo-2.5005*10**7 if n_dens.data==-5000 or T_k.data==-5000 else foo for foo in P.data]

对于我上面的试验,我收到以下错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

如何纠正错误?或者有其他方法可以减少它吗?

【问题讨论】:

  • 我认为您的意思是让else: 下方的行再缩进一级(因为您的代码目前的状态,它会引发IndentationError)。
  • 无论您选择什么,请记住可读代码比单行代码更重要
  • 对改进工作代码的建议通常不是 StackOverflow 的重点,因为我们试图成为特定、狭窄问题的答案的存储库,以避免可能是主观意见问题的问题——我们的姊妹网站Code Review 通常更合适,尽管那里的规则有很大不同。请参阅 A Guide to Code Review For Stack Overflow Users 以获取有关哪些问题在哪里适合,以及如何调整它们以使其符合每个站点的规则的指导。

标签: python arrays


【解决方案1】:

n_dens.data==-5000 产生一个真/假值数组,而不是单个值。所以,if 无法处理。不过,您已经接近这个想法了。您可以在 numpy 中使用 逻辑索引

在python中也不能重载逻辑运算符。因此,numpy 不会像您希望的那样处理它们。所以,你必须做类似的事情

index = np.logical_or(n_dens.data ==-5000, T_k.data==-5000)
P.data[index] = -5000

同样,P.data[np.logical_not(index)] = n_dens.data * T.data 用于 if-else 的第二个分支。

【讨论】:

    【解决方案2】:

    你可以试试这个:

    P.data[(n_dens.data == -5000) | (T_k.data == -5000)] = -5000
    cond = ~(n_dens.data == -5000) & ~(T_k.data == -5000) # 2D array of booleans
    P.data[cond] = n_dens.data[cond] * T_k.data[cond]
    

    一个完整的例子:

    import numpy as np
    from copy import deepcopy
    
    class IMAGE:
        def __init__(self, data):
            self.data = data
            self.shape = self.data.shape
    
    np.random.seed(0)
    P, n_dens, T_k = IMAGE(np.zeros((5,5))), IMAGE(np.reshape(np.random.choice([-5000,1,2],25), (5,5))), IMAGE(3*np.ones((5,5)))
    P1 = deepcopy(P)
    
    # with loop
    for i in range(P.shape[0]):
        for j in range(P.shape[1]):
            if (n_dens.data[i][j]==-5000 or T_k.data[i][j]==-5000):
                P.data[i][j]=-5000
            else :
                P.data[i][j]=n_dens.data[i][j]*T_k.data[i][j]
    
    # vectorized
    P1.data[(n_dens.data == -5000) | (T_k.data == -5000)] = -5000
    cond = ~(n_dens.data == -5000) & ~(T_k.data == -5000) # 2D array of booleans
    P1.data[cond] = n_dens.data[cond] * T_k.data[cond]
    
    cond
    # array([[False,  True, False,  True,  True],
    #   [ True, False,  True, False, False],
    #   [False,  True,  True,  True,  True],
    #   [False,  True,  True,  True,  True],
    #   [False,  True, False, False,  True]], dtype=bool)
    
    # with same output for both
    P.data == P1.data
    # array([[ True,  True,  True,  True,  True],
    #   [ True,  True,  True,  True,  True],
    #   [ True,  True,  True,  True,  True],
    #   [ True,  True,  True,  True,  True],
    #  [ True,  True,  True,  True,  True]], dtype=bool)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2017-05-07
      • 2021-02-24
      相关资源
      最近更新 更多