gpt4 book ai didi

python - 将矩阵中位置低于 0 的所有元素转换为 0 (Python)

转载 作者:行者123 更新时间:2023-11-28 21:38:18 25 4
gpt4 key购买 nike

这是一个矩阵:

matrix = [[1, 1, 1, 0], 
[0, 5, 0, 1],
[2, 1, 3, 10]]

我想将 0 以下的所有元素位置 更改为 0(在同一列上)。

结果矩阵将是:

matrix = [[1, 1, 1, 0], 
[0, 5, 0, 0],
[0, 1, 0, 0]]

到目前为止我已经试过了。返回为空

import numpy as np
def transform(matrix):
newmatrix = np.asarray(matrix)
i = 0
j = 0
for j in range(0,len(matrix[0])-1):
while i < int(len(matrix))-1 and j < int(len(matrix[0]))-1:
if newmatrix[i][j] == 0:
np.put(newmatrix,newmatrix[i+1][j], 0 )
i +=1
return print (newmatrix)

最佳答案

方法一(原创)

import numpy as np
def transform(matrix):
mat = np.asarray(matrix)
mat[np.logical_not(np.not_equal(mat, 0).cumprod(axis=0))] = 0
# Alternatively:
# mat[~(mat != 0).cumprod(axis=0, dtype=np.bool)] = 0
# or,
# mat[~((mat != 0).cumprod(axis=0, dtype=np.bool))] = 0
return mat

然后根据您的示例数据,我得到以下 mat :

In [195]: matrix = [[1, 1, 1, 0], 
...: [0, 5, 0, 1],
...: [2, 1, 3, 10]]

In [196]: transform(matrix)
Out[196]:
array([[1, 1, 1, 0],
[0, 5, 0, 0],
[0, 1, 0, 0]])

方法二(进一步优化)

def transform2(matrix):
mat = np.asarray(matrix)
mat *= (mat != 0).cumprod(axis=0, dtype=np.bool)
return mat

方法三(更优化)

def transform3(matrix):
mat = np.asarray(matrix)
mat *= mat.cumprod(axis=0, dtype=np.bool)
return mat

说明

让我们看一下主要语句(在方法 1 中):

mat[np.logical_not(np.not_equal(mat, 0).cumprod(axis=0))] = 0

我们可以将其拆分为几个“基本”操作:

  1. 创建一个包含 False 的 bool 掩码(数值 0 )其中 mat 的元素是 0True (数字 1 )它们是非零的:

    mask1 = np.not_equal(mat, 0)
  2. 利用数值 False 的事实为 0,使用 cumprod() 函数(一个很好的解释可以在这里找到:https://www.mathworks.com/help/matlab/ref/cumprod.html)

    mask2 = mask1.cumprod(axis=0)

    1*1==10*00*10 ,此“掩码”的所有元素都将是 01 .他们将是 0仅在 mask1 的位置为零及以下 (!) 因为产品沿列 的“累积性质”(因此 axis=0 )。

  3. 现在,我们要设置 mat 的那些元素对应于 0mask20 .为此,我们创建了一个 bool 掩码 True其中 mask20False别处。这可以通过将逻辑(或二进制)NOT 应用于 mask2 来轻松实现。 :

    mask3 = np.logical_not(mask2)

    在这里使用“逻辑”NOT 创建一个 bool 数组,因此我们避免了显式类型转换。

  4. 最后我们使用 Boolean Indexing选择 mat 的那些元素需要设置为 0并将它们设置为 0 :

    mat[mask3] = 0

可选优化

如果您想到了,我们可以通过执行以下操作来摆脱步骤 3 和 4:

mask2 = mask1.cumprod(axis=0, dtype=np.bool) #convert result to boolean type 
mat *= mask2 # combined step 3&4

有关完整的实现,请参阅上面的“方法 2”部分。

性能

有几个额外的答案使用了 numpy.ufunc.accumulate() .从根本上说,所有这些方法都围绕着 0 的想法展开。在 0*anything==0 的意义上是一个“特殊”值或者,就@DSM 的回答而言,即 False=0<True=0并出租 numpy对数组执行“累积”操作。

除了我的方法 #1 比其他方法慢之外,性能有一些变化,但大多数变化很小。

下面是更多功能的一些时序测试。注意:为了正确执行测试,我们需要使用大数组。小型阵列测试将测量开销、现金等。

In [1]: import sys
...: import numpy as np
...:

In [2]: print(sys.version)
...:
3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:14:59)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]

In [3]: print(np.__version__)
...:
1.12.1

In [4]: # Method 1 (Original)
...: def transform1(matrix):
...: mat = np.asarray(matrix)
...: mat[np.logical_not(np.not_equal(mat, 0).cumprod(axis=0))] = 0
...: return mat
...:

In [5]: # Method 2:
...: def transform2(matrix):
...: mat = np.asarray(matrix)
...: mat *= (mat != 0).cumprod(axis=0, dtype=np.bool)
...: return mat
...:

In [6]: # @DSM method:
...: def transform_DSM(matrix):
...: mat = np.asarray(matrix)
...: mat *= np.minimum.accumulate(mat != 0)
...: return mat
...:

In [7]: # @DanielF method:
...: def transform_DanielF(matrix):
...: mat = np.asarray(matrix)
...: mat[~np.logical_and.accumulate(mat, axis = 0)] = 0
...: return mat
...:

In [8]: # Optimized @DanielF method:
...: def transform_DanielF_optimized(matrix):
...: mat = np.asarray(matrix)
...: mat *= np.logical_and.accumulate(mat, dtype=np.bool)
...: return mat
...:

In [9]: matrix = np.random.randint(0, 20000, (20000, 20000))

In [10]: %timeit -n1 transform1(matrix)
22.1 s ± 241 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [11]: %timeit -n1 transform2(matrix)
9.29 s ± 185 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [12]: %timeit -n1 transform3(matrix)
9.23 s ± 180 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [13]: %timeit -n1 transform_DSM(matrix)
9.24 s ± 195 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [14]: %timeit -n1 transform_DanielF(matrix)
10.3 s ± 219 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [15]: %timeit -n1 transform_DanielF_optimized(matrix)
9.27 s ± 187 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

我的初始解决方案(方法 1)最慢,而其他方法要快得多。由于使用 bool 索引,@DanielF 原始方法有点慢(但优化变体与其他优化方法一样快)。

关于python - 将矩阵中位置低于 0 的所有元素转换为 0 (Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48453509/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com