【问题标题】:Numpy unwrap error when using apply() on Pandas dataframe在 Pandas 数据帧上使用 apply() 时出现 Numpy 解包错误
【发布时间】:2020-12-09 13:57:27
【问题描述】:

我有一个 Pandas DataFrame,它有两列包含 [-pi, pi) 范围内的一些角度。我需要计算每行的瞬时角速度,我可以使用 diff() 来完成,但是当我的数据跨越从 pi 到 -pi 的不连续性时,这种天真的方法会失败,例如

我试图在我的列上使用 numpy.unwrap(),但是当我尝试下面的代码时,我得到一个 ValueError。

angle_data["theta"].apply(np.unwrap)
<Traceback message> 
ValueError: diff requires input that is at least one dimensional

如果我将列复制到 Pandas 系列并尝试使用 apply(np.unwrap),也会发生这种情况。 我可以通过这样做来解决这个问题

angle_data["theta"] = pd.Series(np.unwrap(angle_data["theta"]))

或者一次对多个列使用 apply,但我想知道为什么 apply(np.unwrap) 方法不适用于 Pandas 系列。

【问题讨论】:

  • 不使用 diff,也许你可以像here 那样使用 np.arctan2(cos 和 sin 都存在于 numpy 中)
  • 谢谢,我以前没见过这种方法,可能会试一试,尽管从该答案的后续 cmets 来看,与其他解决方法相比,它可能对性能造成太大影响我找到了。
  • 不要太担心性能。我一直在使用它来解决大数据集上的类似问题(实际上是“平均”角度),这不是问题(afaik,因为它直接来自 numpy,它已经比大多数 python 指令快......)

标签: python pandas numpy


【解决方案1】:

来自文档:

Help on function unwrap in module numpy:

unwrap(p, discont=3.141592653589793, axis=-1)
    ...
    Parameters
    ----------
    p : array_like
        Input array.
    ...

您的回溯是说,通过使用 apply,您正在遍历列,然后对每个单独的值应用 unwrap(这与关于 p 的文档背道而驰)。

您可以通过使用这样的自定义打印来查看正在发生的事情:

def my_print(x):
    print(x)
    print('-'*50)
df['theta'].apply(my_print)

您将看到列的每个值都作为参数一个接一个地传递。换句话说,您就像遍历列表一样循环:效率很低。

您已经找到了使用 unwrap 的正确方法:将其直接应用到系列中,而不是对其进行迭代:np.unwrap(df['theta'])。

这是使用所有 numpy 函数的方法(剧透警告:如果放弃“应用”方法,将会获得巨大的性能提升)。

所以作为一个经验法则:尽可能远离“应用”(大多数时候,你确实可以)并坚持使用来自 pandas 的 numpy 或内置函数。

【讨论】:

  • 只是好奇,你说 numpy 函数不会迭代类似数组的对象,它是如何工作的?当然,他们仍然必须以某种方式对其进行迭代吗?是访问数组的方式有所不同吗?
  • 不确定所涉及的机制。它被称为“矢量化”;我怀疑这与 3 个因素有关:聪明的 Python 编码、用 C 编写的核心(比 Python 快)和矩阵运算。其中一些可以阅读here(例如...)
猜你喜欢
  • 2018-07-29
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 2011-02-19
  • 2016-10-15
  • 2018-07-20
  • 1970-01-01
相关资源
最近更新 更多