使用旧版本的 NumPy 格式化二维数组

Formatting 2D array with older version of NumPy

我有一段代码可以将二维数组格式化为特定的字符串格式。该代码片段适用于最新版本的 NumPy(例如 1.9.2),但不适用于 NumPy 1.4.1,这是 CentOS 6.6 的当前版本。

import numpy as np
cfmt = '%14.6E'
vfmt = np.vectorize(cfmt.__mod__)

Traceback (most recent call last):
  File "/usr/lib64/python2.6/site-packages/numpy/lib/function_base.py", line 1762, in __init__
    nin, ndefault = _get_nargs(pyfunc)
  File "/usr/lib64/python2.6/site-packages/numpy/lib/function_base.py", line 1694, in _get_nargs
    raise ValueError, 'failed to determine the number of arguments for %s' % (obj)
ValueError: failed to determine the number of arguments for <method-wrapper '__mod__' of str object at 0xb461e0>

Numpy-discussion 开始,这似乎是 functools.partial 的问题,建议使用 lambda 解决方法。但是,这是我失败的尝试:

vfmt1 = np.vectorize(lambda x: cfmt.__mod__(x))
vfmt2 = np.vectorize(lambda x: cfmt % (x,), ['|S14'])  # attempt to specify otype

# A 2D array with shape (1, 3)
ar = np.array([[1.0e35, 9.999999, 10.0]])

print(vfmt1(ar))  # [['  1.0000' '  9.9999' '  1.0000']]
print(vfmt2(ar))  # [['  1.0000' '  9.9999' '  1.0000']]

这些值似乎是被截短为 8 个字符的字符串,实际上是垃圾。

使用最新版本的 NumPy 的预期格式化结果是:

array([['  1.000000E+35', '  9.999999E+00', '  1.000000E+01']], type='|S14')

关于如何使用旧版本的 NumPy 获得预期输出的任何建议?或者通常如何将数字数组的格式向量化为字符数组?

如果您的输入数组是一维的,一个简单的列表理解就可以了:

>>> ar
array([  1.00000000e+35,   9.99999900e+00,   1.00000000e+01])
>>> ar2 = np.array(["%14.6E" % v for v in ar])
>>> ar2
array(['  1.000000E+35', '  9.999999E+00', '  1.000000E+01'], 
      dtype='|S14')

对于二维数组,嵌套列表理解将起作用。例如,这是一个二维数组 x:

>>> x
array([[  1.00000000e+35,   9.99999900e+00,   1.00000000e+01],
       [  1.23450000e-04,   0.00000000e+00,   1.23000000e+02]])

这是创建字符串列表的嵌套列表理解:

>>> [["%14.6E" % v for v in row] for row in x]
[['  1.000000E+35', '  9.999999E+00', '  1.000000E+01'], ['  1.234500E-04', '  0.000000E+00', '  1.230000E+02']]

如果您需要将结果作为 numpy 数组,只需将其放入对 np.array:

的调用中
>>> np.array([["%14.6E" % v for v in row] for row in x])
array([['  1.000000E+35', '  9.999999E+00', '  1.000000E+01'],
       ['  1.234500E-04', '  0.000000E+00', '  1.230000E+02']], 
      dtype='|S14')