我有一个日期时间对象的 1D numpy 数组,我想抓取所有具有特定月份的对象。我可以通过迭代整个数组来做到这一点:
new_times = []
for time in times:
if time.month == 1:
new_times.append(time)
但这不是很有效,而且看起来也不是很python化。如果这是一个整数月份数组,我可以做类似的事情
arr = np.array([1,1,2,3,4,5,6,1,7,4,8,1])
new_arr = arr[np.where(arr == 1)]
但是,在调用数组对象的属性时,此方法不起作用。有没有一种很好的方法来搜索所有具有特定对象属性的numpy数组元素?
一般来说,我不知道你能比使用vectorize
或frompyfunc
(然后使用标准的 numpy 技术进行过滤等(做得更好:
例如
import datetime
M = np.array([datetime.datetime(1980,i,i) for i in range(1,4)])
M
# array([datetime.datetime(1980, 1, 1, 0, 0),
# datetime.datetime(1980, 2, 2, 0, 0),
# datetime.datetime(1980, 3, 3, 0, 0)], dtype=object)
import operator as op
np.frompyfunc(op.attrgetter("month"),1,1)(M)
# array([1, 2, 3], dtype=object)
np.vectorize(op.attrgetter("month"),otypes=(int,))(M)
# array([1, 2, 3])
在您的具体情况中:
Mnp = M.astype("M8[M]")
Mnp - Mnp.astype("M8[Y]") + 1
# array([1, 2, 3], dtype='timedelta64[M]')
在这里使用hpaulj的方法使用列表理解既简单又快速:
>>> import numpy as np
>>> import datetime as dt
>>> a=np.array([dt.datetime(month=1,day=2,year=2020),dt.datetime(month=2,day=12,year=2019),dt.datetime(month=8,day=26,year=1952)])
>>> [e for e in a.tolist() if e.month<5]
[datetime.datetime(2020, 1, 2, 0, 0), datetime.datetime(2019, 2, 12, 0, 0)]
如果您只想要索引:
>>> [i for i,e in enumerate(a.tolist()) if e.month<5]
[0, 1]
在这里使用pandas.Series
可能是一个很好的帮手,
from datetime import datetime
import numpy as np
import pandas as pd
a = np.array([datetime(2020, m, 1) for m in range(1, 5)])
s = pd.Series(a)
现在,您可以访问月份
s.dt.month
# 0 1
# 1 2
# 2 3
# 3 4
# dtype: int64
a[s.dt.month < 3]
# array([datetime.datetime(2020, 1, 1, 0, 0),
# datetime.datetime(2020, 2, 1, 0, 0)], dtype=object)
这将适用于 datetime.datetime 对象数组以及 np.datetime64。但与往常一样,便利是有代价的,因此列表理解(在 datetime.datetime 的情况下(、np.vectorize
和np.frompyfunc
很可能会运行得更快。