我想让Numpy有效地将数字数组(例如float32)的每个元素转换为格式化数组(即类似字符串的字符串)。通过将每个元素迭代到列表,可以按预期工作:
import numpy as np
a = (10 ** np.arange(-5, 6, 2, dtype='d') * 3.14159).astype('f')
# array([3.14159e-05, 3.14159e-03, 3.14159e-01, 3.14159e+01, 3.14159e+03,
# 3.14159e+05], dtype=float32)
# Good conversion to a list
print([str(x) for x in a])
# ['3.14159e-05', '0.00314159', '0.314159', '31.4159', '3141.59', '314159.0']
print(list(map(lambda x: str(x), a))) # also does the same
# Expected result: a string-like Numpy array
print(repr(np.array([str(x) for x in a])))
# array(['3.14159e-05', '0.00314159', '0.314159', '31.4159', '3141.59',
# '314159.0'], dtype='<U11')
但是,由于map()
或列表推导不了解附加维度的工作原理,因此该示例无法轻松扩展到多维数组。我希望将结果提供为具有类似字符串数据类型的Numpy数组,如上所示。
通常,可以使用numpy.vectorize
来执行此操作,但是我对Numpy 1.15的每次尝试都不会返回预期的结果:
# Bad conversions with np.vectorize, all show the same result
f = np.vectorize(lambda x: str(x))
f = np.vectorize('%s'.__mod__) # equivalent; gives same result
f = np.vectorize(lambda x: '{!s}'.format(x)) # also same, but modern formatter
print(f(a))
# array(['3.141590059385635e-05', '0.003141589928418398',
# '0.31415900588035583', '31.4158992767334', '3141.590087890625',
# '314159.0'], dtype='<U21')
(这些结果不好的原因是,Numpy似乎将数据类型从float32升级为Python的本机双精度;类似于[str(x) for x in a.tolist()]
)
关于如何在任意维数的Numpy数组上使用map()/ list理解和/或修复np.vectorize
以获得等效结果的任何想法?
答案 0 :(得分:1)
np.char.mod
怎么样?
import numpy as np
np.char.mod('%.2f', np.random.rand(8, 8))
它输出
array([['0.04', '0.86', '0.74', '0.45', '0.30', '0.09', '0.65', '0.58'],
['0.96', '0.58', '0.41', '0.29', '0.26', '0.54', '0.01', '0.59'],
['0.38', '0.86', '0.37', '0.14', '0.32', '0.57', '0.19', '0.28'],
['0.91', '0.80', '0.78', '0.39', '0.67', '0.51', '0.16', '0.70'],
['0.61', '0.12', '0.89', '0.68', '0.01', '0.23', '0.57', '0.18'],
['0.71', '0.29', '0.08', '0.01', '0.86', '0.03', '0.79', '0.75'],
['0.44', '0.84', '0.89', '0.75', '0.48', '0.88', '0.69', '0.20'],
['0.36', '0.69', '0.12', '0.60', '0.16', '0.39', '0.15', '0.02']],
dtype='<U4')
答案 1 :(得分:0)
您可以简单地将astype与dtype'str'一起使用
a.astype(dtype=str)
# array(['3.14159e-05', '0.00314159', '0.314159', '31.4159', '3141.59',
# '314159.0'], dtype='<U32')
编辑:刚刚看到您的评论,您已经自己弄清楚了。尽管如此,我会保持答案。