如何将矩阵的浮点数乘以整数?

我试着用下面的代码来乘以矩阵中的浮点数。a 小于1的任何整数,但它不能工作,另一方面,它对元素不是浮点数的矩阵工作正常,即如果你定义matix a = np.arange(9).reshape(3,3) 那么它的工作。

import numpy as np

a = np.linspace(0,1,9).reshape(3,3)

print(a)
print('new matrix')
for x in np.nditer(a, op_flags = ['readwrite']):
  if x in range(0,1):
    x[...] = 100*x
print(a)

解决方案:

In [130]: a = np.linspace(0,1,9).reshape(3,3)                                                          
In [131]: a                                                                                            
Out[131]: 
array([[0.   , 0.125, 0.25 ],
       [0.375, 0.5  , 0.625],
       [0.75 , 0.875, 1.   ]])

我通常不建议使用 nditer 来迭代一个数组。 它很难用对,而且很少能提高速度。 我不知道是谁或者是什么促使人们使用它。 它的文档可以使用一个更强的速度声明。

无论如何,让我们来看看发生了什么。

In [136]: for x in np.nditer(a, op_flags = ['readwrite']): 
     ...:   print(type(x), x, x.shape)   
     ...:   if x in range(0,1): 
     ...:     x[...] = 100*x 
     ...:     print('mul') 
     ...:                                                                                              
<class 'numpy.ndarray'> 0.0 ()
mul
<class 'numpy.ndarray'> 0.125 ()
<class 'numpy.ndarray'> 0.25 ()
<class 'numpy.ndarray'> 0.375 ()
<class 'numpy.ndarray'> 0.5 ()
<class 'numpy.ndarray'> 0.625 ()
<class 'numpy.ndarray'> 0.75 ()
<class 'numpy.ndarray'> 0.875 ()
<class 'numpy.ndarray'> 1.0 ()

nditer 遍历数组的每一个元素(不是行),每次都产生一个0d的视图(shape ()). 这些元素中只有一个是0,所以它乘以100。 其他元素都不在 range(0,1) (仅 0 in range(0,1)其他都是 False).

所以,迭代是工作,即使不是按照你的意图,至少也是编码。

a = np.arange(9).reshape(3,3) 并没有改变什么。 只有0是 in range(0,1),

===

更改 if 检验。

In [146]: a = np.linspace(0,1,9).reshape(3,3)                                                          
In [147]: a                                                                                            
Out[147]: 
array([[0.   , 0.125, 0.25 ],
       [0.375, 0.5  , 0.625],
       [0.75 , 0.875, 1.   ]])
In [148]: for x in np.nditer(a, op_flags = ['readwrite']):  
     ...:   if x<1: 
     ...:     x[...] = 100*x 
     ...:     print('mul') 
     ...:                                                                                              
mul
...
mul
In [149]: a                                                                                            
Out[149]: 
array([[ 0. , 12.5, 25. ],
       [37.5, 50. , 62.5],
       [75. , 87.5,  1. ]])

检验: nditer 是一个 flat 迭代。 在某些方面,这更复杂,因为它需要一个 enumerate 如果我们想修改原始值。

In [150]: a = np.linspace(0,1,9).reshape(3,3)                                                          
In [151]: for i,v in enumerate(a.flat): 
     ...:     if v<1: 
     ...:         a.flat[i] *= 100 
     ...:                                                                                              
In [152]: a                                                                                            
Out[152]: 
array([[ 0. , 12.5, 25. ],
       [37.5, 50. , 62.5],
       [75. , 87.5,  1. ]])

但是,尽管有一些说法在 nditer docs,并没有更快。

In [153]: %%timeit a=np.linspace(0,1,9).reshape(3,3) 
     ...: for i,v in enumerate(a.flat): 
     ...:     if v<1: 
     ...:         a.flat[i] *= 100 
5.4 µs ± 186 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [154]:                                                                                              
In [154]: %%timeit a=np.linspace(0,1,9).reshape(3,3) 
     ...: for x in np.nditer(a, op_flags = ['readwrite']):  
     ...:   if x<1: 
     ...:     x[...] = 100*x 
34.4 µs ± 108 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

===

但通常你不应该在数组上迭代。 一个完整的数组。矢量化,方法是。

In [157]: mask = a<1                                                                                   
In [158]: mask                                                                                         
Out[158]: 
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True, False]])
In [159]: a[mask] *= 100                                                                               
In [160]: a                                                                                            
Out[160]: 
array([[ 0. , 12.5, 25. ],
       [37.5, 50. , 62.5],
       [75. , 87.5,  1. ]])
In [161]: %%timeit a=np.linspace(0,1,9).reshape(3,3) 
     ...: a[a<1] *= 100                                                                                               
12.5 µs ± 184 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

对于这个小例子来说,这比平面枚举要慢。 对于一个大得多的 a 这样做会更好。

给TA打赏
共{{data.count}}人
人已打赏
解决方案

Django测试没有使用AssertRaises增加覆盖率。

2022-5-14 14:00:15

解决方案

Google-Map-React如何获得边界内的标记?

2022-5-14 14:00:17

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索