numpy nthroot的负真实的解- Python

d7v8vwbk  于 2023-08-05  发布在  Python
关注(0)|答案(1)|浏览(85)

我正在使用Python中内置的幂运算来缩放数据。然而,我注意到,当尝试计算负数的n次方根(对于奇数n)时,我得到的x^n = -N的解对应于theta = pi/n,这是一个复数解。理想情况下,我会得到负真实的解x = (-N)^(1/n)
下面是以下内置和NumPy实现。
内置:

# should be -11.28443261177375
>>> (-2967000000)**(1/9)
(10.603898055039648+3.8595032592277083j)

字符串
NumPy:

# should be -11.28443261177375
>>> np.pow(-2967000000, 1/9)
nan


是否有一种有效的方法使用NumPy或内置方法来强制Python使用负真实的解?如果可能的话,我想避免编写一个函数来满足这种需要。我现在用的是np.sign(x)*abs(x)**(1/n)。我能做些什么改进吗?

ds97pgxw

ds97pgxw1#

我做了一些测试,尝试不同的方法,看看哪种方法最快。

import numpy as np
import pandas as pd
import math
import timeit

df = pd.DataFrame({"nums": np.arange(-2967000000, 100, 10000, dtype=float)})

def method1(df=df, n=1/9):
    return df["nums"].apply(lambda x: np.sign(x)*np.abs(x)**n)

def method2(df=df, n=1/9):
    return df["nums"].apply(lambda x: np.sign(x)*np.power(np.abs(x), n))

def method3(df=df, n=1/9):
    return df["nums"].apply(lambda x: math.copysign(x, abs(x)**n))

def method4(df=df, n=1/9):
    x = df["nums"]
    return pd.Series(np.sign(x)*np.abs(x)**n)

def method5(df=df, n=1/9):
    x = df["nums"]
    return pd.Series(np.sign(x)*np.power(np.abs(x), n))

methods = [method1, method2, method3, method4, method5]

N = 7
for method in methods:
    print(method.__name__, timeit.timeit(method, number=N)/N)

字符串
输出量:

method1 0.6219473714285674
method2 0.8631320142857086
method3 0.13383357142856767
method4 0.011573042857110392
method5 0.011473671428575472


因此,直接在pandas Series上使用numpy函数(避免apply)是最快的。这是有意义的,因为numpy在处理数组时速度很快。下一个最快的是使用apply的数学库,这与我刚才所说的numpy在数组上的速度一致。最慢的方法是与apply一起使用的numpy方法,因为它本质上是在 Dataframe 中循环;你不应该在循环时使用numpy。

相关问题