【问题标题】:How to force numpy.genfromtxt to generate a non-structured numpy array?如何强制 numpy.genfromtxt 生成非结构化 numpy 数组?
【发布时间】:2020-02-16 12:43:42
【问题描述】:

在 Python 3 中我会这样做:

s = StringIO(u"1,1.3,abcde\n2,1.3,test")
data = numpy.genfromtxt(s, dtype=[int,float,'U10'], delimiter=',', names=None)

我得到:

array([(1, 1.3, 'abcde'), (2, 1.3, 'test')],
      dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U10')])

我想获得一个没有如下名称的常规 numpy 数组:

array([[1, 1.3, 'abcde'], 
        [2, 1.3, 'test']])

有可能吗?

【问题讨论】:

  • “常规 numpy 数组”只有一种数据类型。如果您尝试最后一段代码,所有对象都将是字符串

标签: python numpy genfromtxt


【解决方案1】:

你得到的是一个“结构化数组”,它优于“常规数组”,因为它支持异构数据类型。您的两列是数字,但一列是文本,因此将您的数据折叠成没有结构的普通 numpy.ndarray 是没有意义的。但如果你愿意,你可以:

numpy.array(data.tolist())

这将为您提供包含所有字符串的 ndarray

array([['1', '1.3', 'abcde'],
       ['2', '1.3', 'test']], dtype='<U32')

但这很少是一个好主意。如果我们有更多的上下文,我们可能会提出更好的整体方法。

【讨论】:

    【解决方案2】:

    带有文本列表:

    In [338]: txt = '''1, 1.3, abcde 
         ...: 2, 1.3, def'''.splitlines()                                           
    

    结构化数组:

    In [339]: np.genfromtxt(txt, dtype=None, delimiter=',', encoding=None)          
    Out[339]: 
    array([(1, 1.3, ' abcde'), (2, 1.3, ' def')],
          dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U6')])
    

    尝试指定对象 - 每个项目都有自己的类型:

    In [340]: np.genfromtxt(txt, dtype=object, delimiter=',', encoding=None)        
    Out[340]: 
    array([[b'1', b' 1.3', b' abcde'],
           [b'2', b' 1.3', b' def']], dtype=object)
    

    它不会尝试将任何字符串转换为数字。

    converters 正确转换列,但由于某种原因仍然是结构化数组:

    In [341]: np.genfromtxt(txt, dtype=object, delimiter=',', encoding=None, convert
         ...: ers={0:int, 1:float})                                                 
    Out[341]: 
    array([(1, 1.3, b' abcde'), (2, 1.3, b' def')],
          dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', 'O')])
    

    但您可以通过列表将结构化数组转换为对象 dtype:

    In [346]: np.genfromtxt(txt, dtype=None, delimiter=',', encoding=None)          
    Out[346]: 
    array([(1, 1.3, ' abcde'), (2, 1.3, ' def')],
          dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U6')])
    In [347]: np.array(_.tolist(), object)                                          
    Out[347]: 
    array([[1, 1.3, ' abcde'],
           [2, 1.3, ' def']], dtype=object)
    

    另一种选择是自己拆分行,构建列表列表。 genfromtxt 正在做这件事,而且花里胡哨。

    In [357]: lines=[] 
         ...: for line in txt: 
         ...:     i = line.split(',') 
         ...:     x = (int(i[0]), float(i[1]), i[2].strip()) 
         ...:     lines.append(x) 
    
    In [358]: lines                                                                 
    Out[358]: [(1, 1.3, 'abcde'), (2, 1.3, 'def')]
    In [359]: np.array(lines,object)                                                
    Out[359]: 
    array([[1, 1.3, 'abcde'],
           [2, 1.3, 'def']], dtype=object)
    

    但请注意,您不能对该对象数组以及数值数组甚至结构化数组的数值字段进行数学运算。

    【讨论】:

    • 伟大而完整的答案!结构化数组和记录数组是一回事吗?
    猜你喜欢
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 2012-08-12
    • 2016-04-28
    • 1970-01-01
    相关资源
    最近更新 更多