这个在整数上运行的numpy算法偶尔会返回浮点数,为什么?

问题描述 投票:2回答:2

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

我本以为这都是整数数学,但我发现在某些情况下,数组会意外地被创建为浮点数!在下面的序列中,我发现了一个问题。

在下面的序列中 p0 是一个 float64 对于 n=1 不过 int64 对于 n>1 我根本不明白为什么会发生这种情况。

我在MacOS上运行numpy 1.17.3版本,安装了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])) 返回 int64 不过 np.hstack(([1, 0, -1], 0*[7])) 返回 float64 所以这是发生在 0*[n] 在其上 np.hstack 触发了上位机的操作。float64.

更新2: 刚刚在 "代码评论 "中问到: 有没有更好的,更干净的,或者 "不那么麻烦 "的方法 让这些六边形的点阵以这种螺旋形的方式排列?

python python-3.x numpy floating-point integer
2个回答
2
投票

是什么触发了整个数组被投向 np.float64时得到的空列表。n=0(n-1)*[n](n-1)*[-n]:

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

np.hstack 从每一个输入数组中构造一个数组进行连接。对每个数组都有一个对 np.atleast_1d,它默认将空数组投递到 np.float64 dtype.这是因为NumPy在连接所有输入之前,先从所有输入中创建ndarrays。

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

1
投票

这样做的原因是NumPy在连接所有输入之前会创建ndarrays.

[0]*n 评估为 []它是一个空列表,因此没有数字类型,因此当它被投向一个数组时,它变成了一个默认数据类型的空数组。也就是使用浮点数.

你可以通过自己使用铸造输入到ndarrays并指定数据类型为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('')

我不能说这是否是预期的行为,但它确实有一些内在的意义。

© www.soinside.com 2019 - 2024. All rights reserved.