在numpy中转换为数组时,列表元素的违反直觉截断?

时间:2012-08-03 04:40:23

标签: python numpy scipy

我注意到numpy中数组的这种违反直觉的行为。我有一个列表,我想将其转换为数组:

>>> a = [['abc', 117858348, 117858388, 'def']]

当我将它转换为数组时,它将元素转换为字符串(没关系),但意外地删除了两个中间元素的最后一位数字:

>>> array(a)
array([['abc', '11785834', '11785838', 'def']], 
      dtype='|S8')

这是什么原因?有没有办法没有这种行为?将列表列表强制转换为数组的原因是为了快速索引某些元素。例如,如果数组x中有索引a列表,则可以执行a[x]来检索它们。如果a是列表列表,则不能,但必须执行[a[i] for i in x]之类的操作。

感谢。

2 个答案:

答案 0 :(得分:4)

这很有趣,运行你的例子给我这个:

>>> numpy.asarray([['abc', 117858348, 117858388, 'def']])
array([['abc', '117', '117', 'def']], 
      dtype='|S3')

我很想知道转换是如何运作的:

>>> help(numpy.asarray)
asarray(a, dtype=None, order=None)
Convert the input to an array.

Parameters
----------
a : array_like
    Input data, in any form that can be converted to an array.  This
    includes lists, lists of tuples, tuples, tuples of tuples, tuples
    of lists and ndarrays.
dtype : data-type, optional
    By default, the data-type is inferred from the input data.

看起来基础类型是inferred from the input data,我想知道这意味着什么,所以我做了

>>> import inspect
>>> print inspect.getsource(numpy.asarray)

我们得到return array(a, dtype, copy=False, order=order),但numpy.array已内置,因此我们会在http://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html处获得文档:

  

dtype:数据类型,可选
  数组所需的数据类型。如果没有给出,那么类型将被确定为保持序列中的对象所需的最小类型。此参数只能用于“upcast”数组。对于向下转换,请使用.astype(t)方法。

好吧,它看起来像是在可能的情况下向上播放,所以在我的情况下是向上转换为长度为3的字符串,因为那是我在序列中最长的字符串,如果我引入了一个更长的字符串它会向上转换,似乎在我的情况下,它没有正确考虑其他类型的数字长度,这可能是一个错误,我不知道......

你可以指定一个长字符串序列

>>> numpy.asarray([['abc', 117858348, 117858388, 'defs']], dtype = 'S20')
array([['abc', '117858348', '117858388', 'defs']], 
  dtype='|S20')

20个字符似乎绰绰有余,虽然它可能消耗更多内存,所以你可以简单地将它设置为最大值......

据我所知,numpy将值存储为同源类型,这就是为什么在创建数组时一切都必须是预先确定的类型。

>>> numpy.__version__
'1.6.1'

$ python --version
Python 2.6.1

$ uname -a
Darwin 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386

我希望这会有所帮助。

答案 1 :(得分:4)

如果使用对象数组,则不会有任何截断。这也可以让你混合使用不同的类型,并使你获得所有的索引信息。

a = [['abc', 117858348, 117858388, 'def']]
a = array(a, dtype=object)
type(a[0, 0])
# <type str>
type(a[0, 1])
# <type int>