【问题标题】:Why can't I raise to a negative power in numpy?为什么我不能在 numpy 中提升到负幂?
【发布时间】:2017-04-07 21:26:12
【问题描述】:

我正在建模黎曼θ函数:

import numpy as np
def theta(s, n=100):
    a_range = np.arange(2, n + 1)
    return 1 + sum(1/(a_range ** s))

对负数s无效;例如theta(-2) 导致这个错误:

      1 def theta(s, n=100):
      2     a_range = np.arange(1)
----> 3     return 1 + sum(1/(a_range ** s))
      4 
      5 theta(-2)

      ValueError: Integers to negative integer powers are not allowed.

这是为什么呢? x^-1 应该只是 1/x 如果我没记错我的数学。

【问题讨论】:

  • 既然,错误信息明确指出:“整数的负整数幂是不允许的。”,为什么不试试:a_range = np.arange(2, n+1, dtype=np.float)
  • 或者只是a_range = np.arange(1.0)就足够了。
  • 就是这样!谢谢。
  • @Evert -- numpy.arange 在浮点值方面存在一些问题,尽管这可能是由浮点精度错误等 (IIRC) 引起的。

标签: python numpy


【解决方案1】:

在 NumPy 中,用于选择像 a_range ** s 这样的操作的输出 dtype 的逻辑基于 dtypes,而不是值。这意味着a_range ** -2 必须具有与a_range ** 2 相同的输出数据类型。

numpy.array([2]) ** 2 这样的东西给出整数输出很重要,这意味着numpy.array([2]) ** -2 必须给出整数或什么都不给出。他们什么也没摘;在 NumPy 中将整数提高到负整数幂是一个错误。

如果要浮点输出,请进行浮点输入:

a_range = np.arange(2, n + 1, dtype=float)

a_range = np.arange(2, n + 1).astype(float)

NumPy 的类型规则有一些奇怪的方面,您可能不会从上面的描述中想到。一种是对于同时涉及标量和数组的操作,标量的 dtype may actually be "demoted" 基于其在输入 dtypes 之前的值用于选择结果 dtype:

>>> (numpy.array([1], dtype='int8') + numpy.int32(1)).dtype
dtype('int8')
>>> (numpy.array([1], dtype='int8') + numpy.array([1], dtype='int32')).dtype
dtype('int32')

在这里,标量 numpy.int32(1) 被“降级”为 int8,但数组不会被降级。 (它实际上比仅仅降级为 int8 更复杂一些,特别是对于有符号/无符号处理;请参阅implementation 了解完整详细信息。)

其次,当涉及到 uint64s 时,NumPy 可能突然看起来可以接受负指数:

>>> numpy.arange(5, dtype='uint64') ** -2
__main__:1: RuntimeWarning: divide by zero encountered in power
array([       inf, 1.        , 0.25      , 0.11111111, 0.0625    ])

这是因为 NumPy 无法为 uint64 值和负值找到足够大的整数 dtype,因此它放弃并将输入强制转换为浮点数。只要避免标量类型“降级”,就可以看到带符号 dtype 的正指数:

>>> numpy.arange(5, dtype='uint64') ** numpy.array([2], dtype='int32')
array([ 0.,  1.,  4.,  9., 16.])

【讨论】:

  • 用于选择操作的输出 dtype 的逻辑 […] 基于 dtypes,而不是值”。这对我来说很有意义,但是为什么在 Python 3 中一个整数除以另一个整数转换为浮点数?
  • @pela:普通的 int/int 除法根本不涉及任何 NumPy 逻辑或 dtype,所以这些都不相关。也就是说,在 Python 3 上将 NumPy 整数除以 NumPy 整数会产生 NumPy 浮点数,但这没问题。选择用于与整数输入 dtype 进行除法的输出 dtype 是浮点 dtype,仍然与输入值无关。没有什么会强制输出 dtype 匹配任何输入 dtype。
  • 啊,抱歉,您指的是 numpy,而不是 Python。也就是说,我倾向于不同意“那没问题”。确保 3/2 = 1 和 –3/2 = –1(如在 Fortran、IDL 和我认为的大多数其他语言中)在 Python 中非常麻烦。无论如何,谢谢你的回复:)
  • @pela:听起来你可能不知道//// 不像其他语言的整数除法运算符那样完全 表现得像其他语言的整数除法运算符,因为它向下而不是向零舍入,但这往往是更有用的行为,尤其是结合% 保持符号右操作数而不是左操作数。 (也许您知道//,但如果您知道的话,我会希望您的投诉措辞不同。)
  • 谢谢,我知道//,但正如你所说的楼层,负数可能不需要。但你可能是对的,一般来说它是更有用的行为。
【解决方案2】:

我为解决这个问题所做的是 -

float_value = float(input_value)
power_value = float_value**-power
final_value = int(power_value)

这里input_value是输入的数字,转换成float,然后我计算负幂,然后取它的int值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-16
    • 2021-08-17
    • 2018-05-29
    • 2019-06-20
    • 1970-01-01
    • 2017-11-13
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多