【问题标题】:How to iterate through a NumPy array while filtering cells values by index and performing math on it如何在按索引过滤单元格值并对其执行数学运算时遍历 NumPy 数组
【发布时间】:2021-10-13 12:26:12
【问题描述】:

我正在尝试在同一迭代中过滤/循环并执行数学运算,但似乎无法找到正确的答案。我有一个 numpy 数组,大小为 6、2,包含两个我想一起减去的值,但是我希望在减去过程开始之前过滤这些值。

因此,如果该值大于另一列中的值,则应从高值中减去最小值,反之亦然。这也需要在一个循环中发生,该循环在执行过滤和数学运算时遍历数组。

这是我的代码示例:

#minus price
print('minus price trying appending')
minus_p_orgp1 = np.append(dif_p_times1, fp, axis=0)
print(minus_p_orgp1)

for ii, vv in enumerate(minus_p_orgp1):
    print('greater')
    greater_1 = np.all(ii > 0, axis=0)
    greater_0 = np.all(ii <= 0, axis=0)
    if greater_1 < greater_0:
        iit = greater_0 - greater_1
    if greater_1 > greater_0:
        iit = greater_1 - greater_0
        print(iit, ii, vv)

ssss = np.zeros(minus_p_orgp1.size - 1)
for i in range(len(minus_p_orgp1) - 1):
    if minus_p_orgp1[i] < minus_p_orgp1[i]:
        ssss[i] = minus_p_orgp1[i + 1] - minus_p_orgp1[i]
    elif minus_p_orgp1[i + 1] > minus_p_orgp1[i]:
        ssss[i] = minus_p_orgp1[i] - minus_p_orgp1[i + 1]
print(ssss)

这是数组的打印,上面的向量是 def_p_time1,下面的向量是 fp:

  minus price trying appending
[[79340.33057205 78379.24102508 72188.80527274 76557.26239563
  72857.90423589 71137.7943199 ]
 [43528.22       43705.         43931.07       44571.24
  44330.43       44465.64      ]]

我可以做些什么来实现我的目标?

我也尝试过让数组成为大小为 6、1 的两个独立向量来完成这个过程。但这似乎也很困难,让我知道你的想法。

我也试过这个;但是在运行代码时它只是打印出零:

trii = np.array([[0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1]])
print(trii)
print(minus_p_orgp1[~(trii >= 1)])
print('it works')
itt = minus_p_orgp1[~(trii >= 1)]
itt1 = minus_p_orgp1[~(trii >= 0)]
sssss = np.zeros(dif_p_times1.size - 1)
ssss = np.zeros(minus_p_orgp1.size - 1)
for i in range(len(dif_p_times1) - 1):
    for ii in range(len(fp) - 1):
        if itt < itt1:
            sssss[i] = itt[i] + itt1[i + 1]
            ssss[i, ii] = fp[ii + 1] - dif_p_times1[i]

        elif itt > itt1:
            sssss[i] = itt[i + 1] + itt1[i]
            ssss[i, ii] = dif_p_times1[i] - fp[ii + 1]
print(sssss)

[[0 0 0 0 0 0]
 [1 1 1 1 1 1]]
[63455.70703442 68744.47486851 77804.44752373 79686.34612013
 69322.78250338 83255.08459329]
it does something
[0. 0. 0. 0. 0.]

这是一个新的尝试,但它仍然不起作用:

ssss = np.zeros(minus_p_orgp1.size - 1)
x = minus_p_orgp1[::2]
y = minus_p_orgp1[::-2]
z = ssss[::2]

for z, x, y in range(len(minus_p_orgp1) - 1):
    
    if x[i + 1] < y[i]:
        z[i] = y[i + 1] - x[i]
    elif x[i + 1] > y[i]:
        z[i] = x[i + 1] - y[i]
print(z)

有没有办法遍历多维列表,这些列表具有不是从重塑/排列函数创建的真实值,并且仍然能够对单个单元格执行布尔过滤,从那里执行数学运算?

我看过 nditer 和 numba,但似乎都做了一个版本,他们转置 2d 数组的维度并减少值,而实际值只返回 1 个值,而不是数组。

【问题讨论】:

  • 您的问题令人困惑。第一个代码块是否有效?您能否提供一组简单的输入,以便我们可以使用 copy-n-paste 运行它。显示结果。当我们有一个清晰的工作示例可供测试和修改时,就更容易提出改进建议。
  • 你的变量为什么叫sssssssssiitrii等等?这不会帮助您或其他任何人了解这里发生了什么。

标签: python arrays numpy loops multidimensional-array


【解决方案1】:

查看你的第一个区块

minus_p_orgp1 = np.append(dif_p_times1, fp, axis=0)
print(minus_p_orgp1)

看起来minus_p_orgp1 是一个 (2,6) 数组,只是 2 个数组的行连接。

for ii, vv in enumerate(minus_p_orgp1):
    print('greater')
    greater_1 = np.all(ii > 0, axis=0)
    greater_0 = np.all(ii <= 0, axis=0)
    if greater_1 < greater_0:
        iit = greater_0 - greater_1
    if greater_1 > greater_0:
        iit = greater_1 - greater_0
        print(iit, ii, vv)

vvminus_p_orgp1 的两行迭代。 ii 迭代地是 0 和 1。所以这个 np.all(ii&gt;0...) business is just testing whether iiis 0 or。它在每个循环中设置iit,但不会将值保存在任何地方。在循环结束时,它具有最后一个值,但那又如何?

在下面size是12(2*6),所以ssssnp.zeros(11)

但迭代超过 2-1,即它只计算 i=0

ssss = np.zeros(minus_p_orgp1.size - 1)
for i in range(len(minus_p_orgp1) - 1):
    if minus_p_orgp1[i] < minus_p_orgp1[i]:
        ssss[i] = minus_p_orgp1[i + 1] - minus_p_orgp1[i]
    elif minus_p_orgp1[i + 1] > minus_p_orgp1[i]:
        ssss[i] = minus_p_orgp1[i] - minus_p_orgp1[i + 1]
print(ssss)

minus_p_orgp1[i] &lt; minus_p_orgp1[i] 是一个包含 6 个 False 的数组。我希望在 if 子句中使用时会引发 ambiguity 错误。

minus_p_orgp1[i + 1] &gt; minus_p_orgp1[i] 更有意义,但仍然不能在elif 中使用。您是跨列还是跨行计算差异?

最初的文字描述有点含糊,但听起来你肯定只是想要两个数组之间的正差:

In [68]: x = np.array([1,3,2,4]); y = np.array([2,1,3,3])
In [69]: x-y
Out[69]: array([-1,  2, -1,  1])
In [70]: y-x
Out[70]: array([ 1, -2,  1, -1])
In [71]: np.abs(x-y)
Out[71]: array([1, 2, 1, 1])

一个迭代的等价物(也适用于列表):

In [72]: z = np.zeros(4, int)
In [73]: for i in range(4):
    ...:     if x[i]>y[i]:
    ...:         z[i] = x[i]-y[i]
    ...:     else:
    ...:         z[i] = y[i]-x[i]
    ...: 
In [74]: z
Out[74]: array([1, 2, 1, 1])

或者简单地说:

In [75]: [abs(i-j) for i,j in zip(x,y)]
Out[75]: [1, 2, 1, 1]

【讨论】:

  • 好吧,你对 abs 计算的权利是一种非常酷的方法。但是,当我这样做时,它起作用了,但是它没有给我我期望的确切数量,如果我使用计算器,那么我会得到不同的结果,并且如果也尝试过矩阵中的其他数字。另外,迭代等效项似乎不起作用,我遇到了与您在上面提到的相同的歧义问题。另外,我希望大多数情况下不使用整数,从某种意义上说,我的意思是应该这样,当我应用代码时,我不必更改大小,而在移动到新数据时不需要更改。
  • 非常感谢您对我的代码的洞察力,这真的有助于我理解我在做什么。但是有没有办法避免 abs 函数,并且可能避免编写迭代 int,以便它对于我输入的大小是动态的?是否还有一个函数可以遍历数组,并从这些索引中执行过滤,因为它似乎也正如你提到的那样,它只是误解了我的布尔数组代码。
  • 但是是的,我正在尝试从两个值中获得正差异。
  • 所以我发现它可能不是 abs 函数,但即使我只是使用 i - j 它与实际数字相差 1000 多一点,在我看来很多。 numpys 数学计算有问题吗?
  • 值 1 和值 2,不是我的值 - 因此我犯了错误,并且看到的值是正确的。
【解决方案2】:

根据 hpaulj 的回答,这行得通:

[abs(i-j) for i,j in zip(x,y)]

【讨论】:

    猜你喜欢
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多