gpt4 book ai didi

python - 不同的切片对相同的元素给出不同的不等式

转载 作者:行者123 更新时间:2023-12-03 17:00:58 28 4
gpt4 key购买 nike

import numpy as np

a = np.array([.4], dtype='float32')
b = np.array([.4, .6])

print(a > b)
print(a > b[0], a > b[1])
print(a[0] > b[0], a[0] > b[1])

[ True False]
[False] [False]
True False

这是怎么回事?是的, b.dtype == 'float64' ,但它的切片也是如此 b[0] & b[1] , 和 a遗体 'float32' .

注意:我问的是为什么会发生这种情况,而不是我知道如何规避它(例如,将两者都转换为 'float64' )。

最佳答案

正如我所指出的 in another answer , numpy 中的类型转换非常复杂,这是您所看到的行为的根本原因。该答案中链接的文档清楚地表明标量(/0d 数组)和 1d 数组在类型转换方面有所不同,因为后者不被视为按值计算。

您已经知道的问题的前半部分:问题在于您的两种情况下类型转换的发生方式不同:

>>> (a + b).dtype
dtype('float64')

>>> (a + b[0]).dtype
dtype('float32')

>>> (a[0] + b[0]).dtype
dtype('float64')

如果我们考虑类型转换表,我相信我们可以理解您的示例中发生了什么:
>> from numpy.testing import print_coercion_tables
can cast
[...]

In these tables, ValueError is '!', OverflowError is '@', TypeError is '#'

scalar + scalar
+ ? b h i l q p B H I L Q P e f d g F D G S U V O M m
? ? b h i l q l B H I L Q L e f d g F D G # # # O ! m
b b b h i l q l h i l d d d e f d g F D G # # # O ! m
h h h h i l q l h i l d d d f f d g F D G # # # O ! m
i i i i i l q l i i l d d d d d d g D D G # # # O ! m
l l l l l l q l l l l d d d d d d g D D G # # # O ! m
q q q q q q q q q q q d d d d d d g D D G # # # O ! m
p l l l l l q l l l l d d d d d d g D D G # # # O ! m
B B h h i l q l B H I L Q L e f d g F D G # # # O ! m
H H i i i l q l H H I L Q L f f d g F D G # # # O ! m
I I l l l l q l I I I L Q L d d d g D D G # # # O ! m
L L d d d d d d L L L L Q L d d d g D D G # # # O ! m
Q Q d d d d d d Q Q Q Q Q Q d d d g D D G # # # O ! m
P L d d d d d d L L L L Q L d d d g D D G # # # O ! m
e e e f d d d d e f d d d d e f d g F D G # # # O ! #
f f f f d d d d f f d d d d f f d g F D G # # # O ! #
d d d d d d d d d d d d d d d d d g D D G # # # O ! #
g g g g g g g g g g g g g g g g g g G G G # # # O ! #
F F F F D D D D F F D D D D F F D G F D G # # # O ! #
D D D D D D D D D D D D D D D D D G D D G # # # O ! #
G G G G G G G G G G G G G G G G G G G G G # # # O ! #
S # # # # # # # # # # # # # # # # # # # # # # # O ! #
U # # # # # # # # # # # # # # # # # # # # # # # O ! #
V # # # # # # # # # # # # # # # # # # # # # # # O ! #
O O O O O O O O O O O O O O O O O O O O O O O O O ! #
M ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
m m m m m m m m m m m m m m # # # # # # # # # # # ! m

scalar + neg scalar
[...]

array + scalar
+ ? b h i l q p B H I L Q P e f d g F D G S U V O M m
? ? b h i l q l B H I L Q L e f d g F D G # # # O ! m
b b b b b b b b b b b b b b e f d g F D G # # # O ! m
h h h h h h h h h h h h h h f f d g F D G # # # O ! m
i i i i i i i i i i i i i i d d d g D D G # # # O ! m
l l l l l l l l l l l l l l d d d g D D G # # # O ! m
q q q q q q q q q q q q q q d d d g D D G # # # O ! m
p l l l l l l l l l l l l l d d d g D D G # # # O ! m
B B B B B B B B B B B B B B e f d g F D G # # # O ! m
H H H H H H H H H H H H H H f f d g F D G # # # O ! m
I I I I I I I I I I I I I I d d d g D D G # # # O ! m
L L L L L L L L L L L L L L d d d g D D G # # # O ! m
Q Q Q Q Q Q Q Q Q Q Q Q Q Q d d d g D D G # # # O ! m
P L L L L L L L L L L L L L d d d g D D G # # # O ! m
e e e e e e e e e e e e e e e e e e F F F # # # O ! #
f f f f f f f f f f f f f f f f f f F F F # # # O ! #
d d d d d d d d d d d d d d d d d d D D D # # # O ! #
g g g g g g g g g g g g g g g g g g G G G # # # O ! #
F F F F F F F F F F F F F F F F F F F F F # # # O ! #
D D D D D D D D D D D D D D D D D D D D D # # # O ! #
G G G G G G G G G G G G G G G G G G G G G # # # O ! #
S # # # # # # # # # # # # # # # # # # # # # # # O ! #
U # # # # # # # # # # # # # # # # # # # # # # # O ! #
V # # # # # # # # # # # # # # # # # # # # # # # O ! #
O O O O O O O O O O O O O O O O O O O O O O O O O ! #
M ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
m m m m m m m m m m m m m m # # # # # # # # # # # ! m

[...]

以上是当前基于值(value)的促销的促销表的一部分。它表示将给定类型的两个 numpy 对象配对时,不同类型对结果类型的贡献(请参阅特定类型的第一列和第一行)。类型应根据 single-character dtype specifications 来理解(在“单字符字符串”下方),特别是 np.dtype('f')对应于 np.float32 (f 代表 C 风格的浮点数)和 np.dtype('d') (d 为 C 型双)到 np.float64 (另见 np.typename('f')'d' 相同)。

我在上表中用黑体标出了两个项目:

scalar f + scalar d --> d
array f + scalar d --> f



现在让我们看看你的案例。前提是你有一个 'f'阵列 a和一个 'd'阵列 b .事实 a只有一个元素并不重要:它是一个长度为 1 的 1d 数组而不是 0d 数组。
  • 当您这样做时a > b您正在比较两个数组,这未在上表中表示。我不确定这里的行为是什么;我的猜测是 a广播到 b的形状,然后将其类型转换为 'd' .我认为这是因为np.can_cast(a, np.float64)Truenp.can_cast(b, np.float32)False .但这只是一个猜测,numpy 中的很多这种机制对我来说并不直观。
  • 当您这样做时a > b[0]您正在比较 'f'数组到 'd'标量,所以根据上面你得到一个 'f'大批。就是这样(a + b[0]).dtype告诉我们。 (当您使用 a > b[0] 时,您看不到转换步骤,因为结果总是一个 bool 值。)
  • 当您这样做时a[0] > b[0]您正在比较 'f'标量到 'd'标量,所以根据上面你得到一个 'd'标量。就是这样(a[0] + b[0]).dtype告诉我们。

  • 所以我相信这完全符合 numpy 中类型转换的怪癖。虽然它可能看起来像一个不幸的极端情况,值为 0.4在 double 和单精度中,这个功能更深入,这个问题是一个很大的红色警告,在混合不同的 dtype 时你应该非常小心。

    最安全的做法是自己转换类型以控制代码中发生的事情。特别是因为有关于重新考虑类型提升的某些方面的讨论。

    关于python - 不同的切片对相同的元素给出不同的不等式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60898613/

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