如何将多个带整数的 NumPy 数组转换为带格式化字符串的 NumPy 数组?

How can I convert several NumPy arrays with ints to a NumPy array with formatted strings?

我有三个长度相同且包含整数的数组:yearsmonthsdays。我想创建一个相同长度的 (NumPy) 数组,其中包含使用 '%i-%2.2i-%2.2i'.

格式的格式化字符串,例如 '(-)yyyy-mm-dd'

对于标量情况,我会做类似的事情

year=2000; month=1; day=1
datestr = '%i-%2.2i-%2.2i' % (year, month, day)

这将产生 '2000-01-01'.

我怎样才能创建这个的矢量版本,例如:

import numpy as np
years  = np.array([-1000, 0, 1000, 2000])
months = np.array([1, 2, 3, 5])
days   = np.array([1, 11, 21, 31])
datestr_array = numpy.somefunction(years, months, days, format='%i-%2.2i-%2.2i', ???)

请注意,我感兴趣的日期范围介于 -2000 年和 +3000 年(CE)之间,因此 Python 的 datetime 和 Pandas' DateTimeIndex 没有提供解决方案。

说明

让我们创建一个函数,将 any 日期无限制地转换为 yyyy-mm-dd 字符串。我们可以使用字符串格式化,在这里我们创建一个预定义的字符串并简单地格式化相关数据。我们还需要将长度格式化为在 'fill it out' 前面有零,即 2001-05-20.

为了能够 运行 这个函数,所有相应的年月日必须组合在一起,这可以通过 zip 函数来实现,该函数将列之间的行分组为元组。我们最好将其转换为 numpy 数组。

现在我们有了正确的元组形式的数据,让我们通过我们的函数来解析它。我们可以使用 apply 创建一个新数组,即 numpy.apply_on_axis(func, axis, data)。因为元组在第二个轴上,所以axis参数必须设置为1。

代码

def FormatDate(data):
    # Where data is a tuple for y, m, d
    return "{0:04}-{1:02}-{2:02}".format(data[0], data[1], data[2]) # Note that this formatting can later be update to account for some weirdness

# Convert the data into tuples where y, m, d are aligned in rows
converted = numpy.array(list(zip(years, months, days)))

# Now, lets apply that function to make the tuples all dates
datestr_array = numpy.apply_along_axis(FormatDate, 1, converted)

一个简单的列表理解会比 numpy 函数更快:

['%i-%2.2i-%2.2i'%(y,m,d) for y,m,d in zip(years, months,days)]

对于数据帧

arr = df[['year','month','day']].values   # a (n,3) array
['%i-%2.2i-%2.2i'%(y,m,d) for y,m,d in arr]

添加 arr=arr.tolist() 可能会增加一些速度,因为列表的迭代比数组快。