对NumPy数组的元素执行操作

时间:2014-08-25 21:41:14

标签: python arrays object numpy

是否有更快/更智能的方法对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

这显然不起作用。

我有一个脚本,我需要不断变化的(更长的)阵列(年,月,小时......)。当然,我总是可以为所有内容定义一个单独的数组,但是应该有一个更优雅的解决方案。

2 个答案:

答案 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)(或类似的东西)看起来并不优雅。