【问题标题】:Converting a 1D numpy array to a list of lists将一维 numpy 数组转换为列表列表
【发布时间】:2013-12-03 18:44:52
【问题描述】:

我想将一维 numpy 数组拆分为列表列表,但我不确定如何做到这一点。

基本上我正在处理一个充满标签的数组:

array(['java database servlets derby', 'java graphics groovy awt basic',
       'java lucene', ..., 'javascript android',
       'iphone ios ipad file uiimage',
       'javascript jquery transition effect'], dtype=object)

有形状:

(5000L,)

如您所见,每一行都包含由空格分隔的标签。我想将每一行存储为一个列表,并将所有标签作为单独的元素,并将这些列表组合成一个列表列表。 结果应该是这样的:

list_of_lists = [["tag","tag","tag"],["tag","tag","tag"]...]

我怎样才能做到这一点?如果你们知道实现我想要的更好的方法(即我可以访问每个标签作为指定行的元素的数据结构),我会很高兴听到它。

提前致谢。

【问题讨论】:

  • 你为什么要把它设为np.array,而不是作为 Python 列表?
  • 我使用的文件阅读器 (pandas.to_csv) 返回一个 np.array 对象。

标签: python arrays list numpy


【解决方案1】:

使用列表理解,str.split

>>> from numpy import array
>>> a = array(['java database servlets derby', 'java graphics groovy awt basic',
...            'java lucene', 'javascript android',
...            'iphone ios ipad file uiimage',
...            'javascript jquery transition effect'])
>>> list_of_lists = [x.split() for x in a]
>>> list_of_lists
[['java', 'database', 'servlets', 'derby'],
 ['java', 'graphics', 'groovy', 'awt', 'basic'],
 ['java', 'lucene'],
 ['javascript', 'android'],
 ['iphone', 'ios', 'ipad', 'file', 'uiimage'],
 ['javascript', 'jquery', 'transition', 'effect']]

【讨论】:

    【解决方案2】:

    dtype=object的数组和falsetru答案中的版本有dtype='|S35'的字幕区别。第一个是指向字符串的指针数组,另一个是 6 个长度为 35 的字符串,共 210 个字节。 [x.split() for x in a] 对两者都是一样的。但是object 数组允许:

    for i in range(6): a[i]=a[i].split()
    

    生产

    array([['java', 'database', 'servlets', 'derby'],
           ['java', 'graphics', 'groovy', 'awt', 'basic'], ['java', 'lucene'],
           ['javascript', 'android'],
           ['iphone', 'ios', 'ipad', 'file', 'uiimage'],
           ['javascript', 'jquery', 'transition', 'effect']], dtype=object)
    

    如果所有这些子列表的长度相同,或者填充到相同的长度,则可以将它们放入结构化数组中。例如

    array([('java', 'database', 'servlets', 'derby', ''),
           ('java', 'graphics', 'groovy', 'awt', 'basic'),
           ('java', 'lucene', '', '', ''),
           ('javascript', 'android', '', '', ''),
           ('iphone', 'ios', 'ipad', 'file', 'uiimage'),
           ('javascript', 'jquery', 'transition', 'effect', '')], 
          dtype=[('f0', 'S10'), ('f1', 'S10'), ('f2', 'S10'), ('f3', 'S10'), ('f4', 'S10')])
    

    然后您可以按名称访问所有“行”中的特定字段

    a2['f0']
    # array(['java', 'java', 'java', 'javascript', 'iphone', 'javascript'],dtype='|S10')
    

    http://docs.scipy.org/doc/numpy/user/basics.rec.html

    【讨论】:

      【解决方案3】:

      这是 numpy,请不要使用循环:P 您可以使用 np.char.split 一次将 split 应用于数组的所有元素:

      A = np.char.split(A)
      

      如果你真的只是想要,你不需要把它列成清单

      一种数据结构,我可以在其中访问每个标签作为指定行的元素

      只是数组可以正常工作:

      >>> A = np.char.split(A)
      >>> A[0]
      ['java', 'database', 'servlets', 'derby']
      >>> A
      array([['java', 'database', 'servlets', 'derby'],
             ['java', 'graphics', 'groovy', 'awt', 'basic'], ['java', 'lucene'],
             ['javascript', 'android'],
             ['iphone', 'ios', 'ipad', 'file', 'uiimage'],
             ['javascript', 'jquery', 'transition', 'effect']], dtype=object)
      

      但您可以使用以下方法转换为列表:

      >>> A.tolist()
      [['java', 'database', 'servlets', 'derby'],
       ['java', 'graphics', 'groovy', 'awt', 'basic'],
       ['java', 'lucene'],
       ['javascript', 'android'],
       ['iphone', 'ios', 'ipad', 'file', 'uiimage'],
       ['javascript', 'jquery', 'transition', 'effect']]
      

      (请注意,如果您的 dtype 是 object,请先使用 A = A.astype('S') 使其成为字符串数组。)

      说实话,在一个长度为 5000 的数组中,这似乎与循环理解的速度差不多。 np.char 在幕后可能并没有太大的不同。

      顺便说一句,如果您没有将 pandas 用于其他任何事情,您可以使用 numpy 本身阅读文本。如果您的文件如下所示:

      java database servlets derby
      java graphics groovy awt basic
      java lucene
      javascript android
      iphone ios ipad file uiimage
      javascript jquery transition effect
      

      然后:

      A = np.genfromtxt('tags.txt', dtype='S', delimiter='\n')
      A = np.char.split(A)
      

      【讨论】:

      • 我在[x.split() for x in a.tolist()] 上的时间最好,是char.split 时间的一半。这是一个小例子。 char.split 的文档说:Calls 'str.rsplit' element-wise. 字符串和对象数组没有像数值数组那样针对速度进行优化。
      • 是的,@hpaulj,对我来说,列表很长,所有时间都在 5% 以内。即使其他一切都相同,我个人也会尝试使用矢量化解决方案,但这更多的是一种风格偏好,而不是任何真实的东西。我发现没有多少人知道np.char,所以我想指出这一点,因为在许多情况下,替代列表理解解决方案是一个真正的痛苦,尤其是对于二维或更大的数组。
      • np.char._vec_string(a,object_,'split') 稍微快一些,因为它可以在没有参数的情况下调用split_vec_stringC 代码,但由于它必须调用像 split 这样的 Py 方法,它不会获得速度。 numpy / core / src / multiarray / multiarraymodule.c
      猜你喜欢
      • 2018-02-26
      • 2014-11-14
      • 2015-08-18
      • 1970-01-01
      • 2011-12-04
      • 2017-03-08
      • 2015-01-07
      • 1970-01-01
      相关资源
      最近更新 更多