在numpy中将int数组转换为字符串数组而不截断

Posted

技术标签:

【中文标题】在numpy中将int数组转换为字符串数组而不截断【英文标题】:Converting int arrays to string arrays in numpy without truncation 【发布时间】:2012-04-15 01:48:42 【问题描述】:

在numpy中尝试将int数组转换为字符串数组

In [66]: a=array([0,33,4444522])
In [67]: a.astype(str)
Out[67]: 
array(['0', '3', '4'], 
      dtype='|S1')

不是我想要的

In [68]: a.astype('S10')
Out[68]: 
array(['0', '33', '4444522'], 
      dtype='|S10')

这行得通,但我必须知道 10 足以容纳我最长的字符串。有没有办法在不提前知道你需要什么大小的字符串的情况下轻松做到这一点?它只是悄悄地截断你的字符串而不抛出错误,这似乎有点危险。

【问题讨论】:

对于 2018 年及以后的访问者:a.astype(str) 现在将完全按照预期工作。 【参考方案1】:

同样,这可以在纯 Python 中解决:

>>> map(str, [0,33,4444522])
['0', '33', '4444522']

或者如果你需要来回转换:

>>> a = np.array([0,33,4444522])
>>> np.array(map(str, a))
array(['0', '33', '4444522'], 
      dtype='|S7')

【讨论】:

谢谢。我想我需要更加熟悉地图。 list(map(str, [0,33,4444522]))【参考方案2】:

你可以留在 numpy,做

np.char.mod('%d', a)

这比 map 或对 10 个元素的列表解析快两倍,对 100 个元素快四倍。这个和其他字符串操作记录在 here。

【讨论】:

很酷,但我找不到这方面的文档,如果可能的话,你能提供一个链接吗? @MikhailV 当然,刚刚添加了答案的链接。【参考方案3】:

使用arr.astype(str),因为numpy 现在支持intstr 的转换并获得所需的结果:

import numpy as np

a = np.array([0,33,4444522])

res = a.astype(str)

print(res)

array(['0', '33', '4444522'], 
      dtype='<U11')

【讨论】:

【参考方案4】:

你可以像这样找到最小的足够宽度:

In [3]: max(len(str(x)) for x in [0,33,4444522])
Out[3]: 7

或者,只需从字符串列表构造ndarray

In [7]: np.array([str(x) for x in [0,33,4444522]])
Out[7]: 
array(['0', '33', '4444522'], 
      dtype='|S7')

或者,使用map()

In [8]: np.array(map(str, [0,33,4444522]))
Out[8]: 
array(['0', '33', '4444522'], 
      dtype='|S7')

【讨论】:

对于大型数组,map() 是比列表推导更好的选择,因为它将代码的执行推送到 C 中。 @JoelCornett 有时map 可能会稍微快一些(在这个例子中,它比我使用列表推导快大约 3%),但情况并非总是如此,并且考虑了列表推导更蟒蛇。见***.com/a/1247490/1191119 @jorgeca:当然,并非总是如此。顺便说一句,在我进行研究时,我偶然发现了 Guido 的 this enlightening article。 @JoelCornett 绝对是一本好书。我知道,但值得重温。 @jorgeca 这篇文章似乎已经移动/蒸发了——知道它现在在哪里吗?我在this list of essays 中找不到它,也没有在 python.org 上搜索 list2str...【参考方案5】:

np.apply_along_axis(lambda y: [str(i) for i in y], 0, x)

例子

>>> import numpy as np

>>> x = np.array([-1]*10+[0]*10+[1]*10)
array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  0,  0,  0,  0,  0,  0,
        0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1])

>>> np.apply_along_axis(lambda y: [str(i) for i in y], 0, x).tolist()
['-1', '-1', '-1', '-1', '-1', '-1', '-1', '-1', '-1', '-1', '0', '0',
 '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1',
 '1', '1', '1', '1']

【讨论】:

以上是关于在numpy中将int数组转换为字符串数组而不截断的主要内容,如果未能解决你的问题,请参考以下文章

将 ctypes int** 转换为 numpy 二维数组

如何在java中将字符串数组转换为int数组[重复]

在 C 中将字符串数组转换为 Int 数组的最佳方法

如何在 Numpy 中将索引数组转换为掩码数组?

如何在 NumPy 中将 HDF5 2D 数组转换为 1D?

如何在 C++ 中将数字字符串转换为 int 数组 [重复]