numpy nthroot的负真实的解- Python

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

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

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

字符串
NumPy:

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


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

ds97pgxw

ds97pgxw1#

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

  1. import numpy as np
  2. import pandas as pd
  3. import math
  4. import timeit
  5. df = pd.DataFrame({"nums": np.arange(-2967000000, 100, 10000, dtype=float)})
  6. def method1(df=df, n=1/9):
  7. return df["nums"].apply(lambda x: np.sign(x)*np.abs(x)**n)
  8. def method2(df=df, n=1/9):
  9. return df["nums"].apply(lambda x: np.sign(x)*np.power(np.abs(x), n))
  10. def method3(df=df, n=1/9):
  11. return df["nums"].apply(lambda x: math.copysign(x, abs(x)**n))
  12. def method4(df=df, n=1/9):
  13. x = df["nums"]
  14. return pd.Series(np.sign(x)*np.abs(x)**n)
  15. def method5(df=df, n=1/9):
  16. x = df["nums"]
  17. return pd.Series(np.sign(x)*np.power(np.abs(x), n))
  18. methods = [method1, method2, method3, method4, method5]
  19. N = 7
  20. for method in methods:
  21. print(method.__name__, timeit.timeit(method, number=N)/N)

字符串
输出量:

  1. method1 0.6219473714285674
  2. method2 0.8631320142857086
  3. method3 0.13383357142856767
  4. method4 0.011573042857110392
  5. method5 0.011473671428575472


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

展开查看全部

相关问题