是否有更快/更智能的方法对numpy数组的每个元素执行操作?我特别拥有的是日期时间对象列表,例如:
hh = np.array( [ dt.date(2000, 1, 1), dt.date(2001, 1, 1) ] )
要获取我现在所做的年份列表:
years = np.array( [ x.year for x in hh ] )
有更聪明的方法吗?我在想像
hh.year
这显然不起作用。
我有一个脚本,我需要不断变化的(更长的)阵列(年,月,小时......)。当然,我总是可以为所有内容定义一个单独的数组,但是应该有一个更优雅的解决方案。
答案 0 :(得分:2)
如果你为每个元素评估一个python表达式,那么迭代是用C ++还是用Python完成并不重要。重要的是评估(in-loop)表达式的python复杂性。这意味着:如果你的(in-loop)表达式需要1微秒(一个非常简单的脚本),那么它将比使用python迭代或C ++迭代(你在C ++和PyObjects之间有一个“编组”)之间的差异要困难得多,这也适用于python函数。
出于这个原因,调用vectorize
是在Python中完成的:在里面调用的是python代码。 vectorize
背后的想法是不性能,但是代码可读性和迭代的简易性:vectorize
执行内省(函数的参数)并且很好地用于N维迭代(即lambda x,y: x+y
自动用于迭代二维。)
所以:不,没有“快速”方式来迭代python代码。最重要的速度是内部python代码的速度。
修改:您的-desired- hh.year
在groovy中看起来像hh*.year
等效,但即使在引擎盖下也与内部代码迭代相同。理解是python中最快(和等效)的方式。真正的遗憾是被迫:
years = np.array( [ x.year for x in hh ] )
(这会强制你创建另一个可证明的巨大尺寸),而不是让你使用任何类型的迭代器:
years = np.array( x.year for x in hh )
编辑(@Jaime的建议):您无法从迭代器中使用该函数构造array
。为此,您必须使用:
np.fromiter(x.year for x in hh, dtype=int, count=len(x))
可以节省构建中间数组的时间和内存。这种精确的方法适用于任何序列,以避免内部列表创建(这将是您的情况)但不适用于其他类型的生成器,以备将来需要的情况。
答案 1 :(得分:0)
您可以使用numpy.vectorize。
进行一些基准测试,性能非常相似(vectorize
比列表理解稍慢),在我看来numpy.vectorize(lambda j: j.year)(hh)
(或类似的东西)看起来并不优雅。