How to do element-wise rounding of NumPy array to first non-zero digit?
我想通过以下方式对numpy数组的元素进行"四舍五入"(不是精确的数学舍入):
给出一个数值介于0.00001至9.99999之间的Nump NxN或NxM 2D数组,例如
1 2 3 4 5 | a=np.array([[1.232, 1.872,2.732,0.123], [0.0019, 0.025, 1.854, 0.00017], [1.457, 0.0021, 2.34 , 9.99], [1.527, 3.3, 0.012 , 0.005]] ) |
我基本上想通过选择每个元素的第一个非零数字(不管后面第一个非零数字后面的数字)来"四舍五入"这个numpy数组
给出输出:
1 2 3 4 5 | output =np.array([[1.0, 1.0, 2.0, 0.1], [0.001, 0.02, 1.0, 0.0001], [1.0, 0.002, 2 , 9.0], [1, 3, 0.01 , 0.005]] ) |
感谢您的帮助!
您想要做的是保持固定数量的有效数字。
此功能未集成到NumPy中。
要仅获取1个有效数字,可以查看@PaulPanzer或@darcamo答案(假设您只有正值)。
如果您希望某件作品能够达到指定数量的有效数字,则可以使用以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def significant_figures(arr, num=1): # : compute the order of magnitude order = np.zeros_like(arr) mask = arr != 0 order[mask] = np.floor(np.log10(np.abs(arr[mask]))) del mask # free unused memory # : compute the corresponding precision prec = num - order - 1 return np.round(arr * 10.0 ** prec) / 10.0 ** prec print(significant_figures(a, 1)) # [[1.e+00 2.e+00 3.e+00 1.e-01] # [2.e-03 2.e-02 2.e+00 2.e-04] # [1.e+00 2.e-03 2.e+00 1.e+01] # [2.e+00 3.e+00 1.e-02 5.e-03]] print(significant_figures(a, 2)) # [[1.2e+00 1.9e+00 2.7e+00 1.2e-01] # [1.9e-03 2.5e-02 1.9e+00 1.7e-04] # [1.5e+00 2.1e-03 2.3e+00 1.0e+01] # [1.5e+00 3.3e+00 1.2e-02 5.0e-03]] |
编辑
对于截断的输出,在
您可以使用
1 2 3 4 5 6 7 | po10 = np.logspace(-10,10,21) oom = po10[po10.searchsorted(a)-1] a//oom*oom # array([[1.e+00, 1.e+00, 2.e+00, 1.e-01], # [1.e-03, 2.e-02, 1.e+00, 1.e-04], # [1.e+00, 2.e-03, 2.e+00, 9.e+00], # [1.e+00, 3.e+00, 1.e-02, 5.e-03]]) |
首先使用
获得数组中每个数字的10的幂
1 | powers = np.floor(np.log10(a)) |
在您的示例中,这给了我们
1 2 3 4 | array([[ 0., 0., 0., -1.], [-3., -2., 0., -4.], [ 0., -3., 0., 0.], [ 0., 0., -2., -3.]]) |
现在,如果我们将数组中的第
那么完整的解决方案只是下面的代码
1 2 | powers = np.floor(np.log10(a)) 10**powers * np.floor(a/10**powers) |
大于或等于10的数字呢?
为此,您可以简单地获取数组中原始值的
1 2 3 4 5 | powers = np.floor(np.log10(a)) result = 10**powers * np.floor(a/10**powers) mask = a >= 10 result[mask] = np.floor(a[mask]) |
您也可以使用掩码来避免计算将在以后替换的数字的幂和对数。