【问题标题】:This numpy algorithm operating on integers occasionally returns floats, why?这个在整数上运行的 numpy 算法偶尔会返回浮点数,为什么?
【发布时间】:2020-04-23 08:23:28
【问题描述】:

这是我正在重写的六边形晶格上生成点同心环的算法的一部分。

我以为这都是整数数学,但我发现在某些情况下,数组会意外地创建为浮点数!

在下面的序列中,p0float64 对应于 n=1int64 对应于n>1,我根本不知道为什么会这样。

我正在运行 numpy 版本 1.17.3,在 MacOS 上安装 Python 3.7.3 的 Anaconda

import numpy as np
n_max = 3
for n in range(1, n_max+1):
    seq = np.arange(n, -n-1, -1, dtype=int)
    p0  = np.hstack((seq, (n-1)*[-n], seq[::-1], (n-1)*[n]))
    print('n: ', n)
    print('seq: ', seq)
    print('p0: ', p0.dtype, p0)
    print('')

返回

n:  1
seq:  [ 1  0 -1]
p0:  float64 [ 1.  0. -1. -1.  0.  1.]

n:  2
seq:  [ 2  1  0 -1 -2]
p0:  int64 [ 2  1  0 -1 -2 -2 -2 -1  0  1  2  2]

n:  3
seq:  [ 3  2  1  0 -1 -2 -3]
p0:  int64 [ 3  2  1  0 -1 -2 -3 -3 -3 -3 -2 -1  0  1  2  3  3  3]

这是预期的行为吗?

更新1:好的np.hstack(([1, 0, -1], 1*[7]))返回int64np.hstack(([1, 0, -1], 0*[7]))返回float64,所以0*[n]np.hstack操作的元组中的出现触发了转至float64

更新 2: 刚刚在 Code Review 中询问:Is there a better, cleaner or otherwise “less tricky” way to get these hexagonal arrays of dots arranged in this spiral pattern?

【问题讨论】:

  • 我自己的期望是空数组根本没有内容类型(除非我们强迫他们这样做)。连接一个空数组不应该改变类型。
  • @aka.nice 同意,这就是我所期望的,这真是一个惊喜!

标签: python python-3.x numpy floating-point integer


【解决方案1】:

触发整个数组被强制转换为np.float64,是n=0(n-1)*[n](n-1)*[-n]时得到的空列表:

print((n-1)*[n])
# []

np.hstack 从要连接的每个输入数组构造一个数组。对于每个数组,都会调用np.atleast_1d,默认情况下会将空数组转换为np.float64 dtype:

np.atleast_1d([])
# array([], dtype=float64)

【讨论】:

    【解决方案2】:

    这样做的原因是 NumPy 在连接它们之前从所有输入创建 ndarray。

    [0]*n 的计算结果为 [],这是一个空列表,因此没有数值类型,因此在转换为数组时,它会变成一个具有默认数据类型 which is to use a float 的空数组。

    您可以通过自己将输入转换为 ndarray 并将数据类型指定为 int 来避免这种情况,例如:

    import numpy as np
    n_max = 3
    for n in range(1, n_max+1):
        seq = np.arange(n, -n-1, -1, dtype=int)
        p0  = np.hstack((seq, np.array((n-1)*[-n], dtype=np.int32), seq[::-1], np.array((n-1)*[-n], dtype=np.int32)))
        print('n: ', n)
        print('seq: ', seq)
        print('p0: ', p0.dtype, p0)
        print('')
    

    我真的不能说这是否是预期的行为,但它在本质上确实有些道理。

    【讨论】:

    • 感谢您的回答!将数组预先转换为 int 或(甚至更糟)捕获 n<1 情况都有效。
    猜你喜欢
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 2022-11-29
    相关资源
    最近更新 更多