【问题标题】:numpy apply along axis not working with weekdaynumpy 沿轴应用不适用于工作日
【发布时间】:2018-07-08 18:54:27
【问题描述】:

我有一个 numpy 数组:

>>> type(dat)
Out[41]: numpy.ndarray

>>> dat.shape
Out[46]: (127L,)

>>> dat[0:3]
Out[42]: array([datetime.date(2010, 6, 11), datetime.date(2010, 6, 19), datetime.date(2010, 6, 30)], dtype=object)

我想获取此数组中每个日期的工作日,如下所示:

>>> dat[0].weekday()
Out[43]: 4

我尝试使用以下方法,但没有任何效果:

import pandas as pd
import numpy as np
import datetime as dt

np.apply_along_axis(weekday,0,dat)
NameError: name 'weekday' is not defined

np.apply_along_axis(dt.weekday,0,dat)
AttributeError: 'module' object has no attribute 'weekday'

np.apply_along_axis(pd.weekday,1,dat)
AttributeError: 'module' object has no attribute 'weekday'

np.apply_along_axis(lambda x: x.weekday(),0,dat)
AttributeError: 'numpy.ndarray' object has no attribute 'weekday'

np.apply_along_axis(lambda x: x.dt.weekday,0,dat)
AttributeError: 'numpy.ndarray' object has no attribute 'dt'

这里有什么我遗漏的吗?

【问题讨论】:

  • weekdaydatetime.date 对象的一个​​方法。 apply_along_axis 需要一个函数。只需使用列表理解进行计算。即使你可以让它工作,apply_along_axis 也不会加快速度。

标签: python pandas numpy datetime weekday


【解决方案1】:

np.apply_along_axis 对一维数组没有多大意义。在 2d 或更高的数组中,它将函数应用于该数组中的 1d 切片。关于该功能:

这个函数应该接受一维数组。它适用于一维 arr 沿指定轴的切片。

这个nameerror 是在运行apply 之前生成的。你没有定义weekday 函数:

np.apply_along_axis(weekday,0,dat)
NameError: name 'weekday' is not defined

weekday 是日期方法,而不是 dt 模块中的函数:

np.apply_along_axis(dt.weekday,0,dat)
AttributeError: 'module' object has no attribute 'weekday'

pandas 中也没有定义:

np.apply_along_axis(pd.weekday,1,dat)
AttributeError: 'module' object has no attribute 'weekday'

这看起来更好,但 apply_along_axis 将数组 (1d) 传递给 lambdaweekday 不是数组方法。

np.apply_along_axis(lambda x: x.weekday(),0,dat)
AttributeError: 'numpy.ndarray' object has no attribute 'weekday'

而且数组也没有dt 属性。

np.apply_along_axis(lambda x: x.dt.weekday,0,dat)
AttributeError: 'numpy.ndarray' object has no attribute 'dt'

所以让我们忘记apply_along_axis


定义一个样本,首先是列表,然后是对象数组:

In [231]: alist = [datetime.date(2010, 6, 11), datetime.date(2010, 6, 19), datetime.date(2010, 6, 30)]
In [232]: data = np.array(alist)
In [233]: data
Out[233]: 
array([datetime.date(2010, 6, 11), datetime.date(2010, 6, 19),
       datetime.date(2010, 6, 30)], dtype=object)

为方便起见,weekday 的 lambda 版本:

In [234]: L = lambda x: x.weekday()

这可以通过多种方式迭代应用:

In [235]: [L(x) for x in alist]
Out[235]: [4, 5, 2]
In [236]: [L(x) for x in data]
Out[236]: [4, 5, 2]
In [237]: np.vectorize(L)(data)
Out[237]: array([4, 5, 2])
In [238]: np.frompyfunc(L,1,1)(data)
Out[238]: array([4, 5, 2], dtype=object)

我刚刚对 3000 项列表进行了时间测试。列表理解是最快的(正如我从过去的测试中所预期的那样),但时间差异并不大。最大的时间消费者只是运行x.weekday() 3000 次。

【讨论】:

  • alist throws TypeError: descriptor 'date' requires a 'datetime.datetime' object but received a 'int'
【解决方案2】:

您可以尝试对 weekday 函数进行矢量化处理,以便将其按元素应用于数组。

weekday_func = lambda x: x.weekday()
get_weekday = np.vectorize(weekday_func)
get_weekday(dat)

【讨论】:

    猜你喜欢
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    相关资源
    最近更新 更多