【问题标题】:numpy genfromtxt - infer column header if headers not providednumpy genfromtxt - 如果未提供标题,则推断列标题
【发布时间】:2020-11-04 14:15:23
【问题描述】:

我了解使用genfromtxtdefaultfmt 参数可用于推断默认列名,如果列名不在输入数据中,这很有用。而defaultfmt,如果未提供,则默认为f%i。例如

>>> data = StringIO("1 2 3\n 4 5 6")
>>> np.genfromtxt(data, dtype=(int, float, int))
array([(1, 2.0, 3), (4, 5.0, 6)],
  dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<i8')])

所以这里我们有自动生成的列名f0f1f2

但是如果我想让 numpy 推断 both 列标题和数据类型怎么办?我以为你用dtype=None 来做。像这样

>>> data3 = StringIO("1 2 3\n 4 5 6")
>>> np.genfromtxt(data3, dtype=None, ???)  # some parameter combo
array([(1, 2, 3), (4, 5, 6)],
  dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8')])  

我仍然想要f0f1...等自动生成的列名。我希望 numpy 能够根据数据自动确定数据类型,我认为这就是 dtype=None 的全部意义所在。

编辑 但不幸的是,这并不总是有效。

当我同时有浮点数和整数时,这种情况有效。

>>> data3b = StringIO("1 2 3.0\n 4 5 6.0")
>>> np.genfromtxt(data3b, dtype=None)
array([(1, 2, 3.), (4, 5, 6.)],
  dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<f8')])

所以 numpy 正确推断前 2 列的数据类型为 i8,最后一列为 f8。

但是,如果我提供所有整数,推断的列名称就会消失。

>>> data3c = StringIO("1 2 3\n 4 5 6")
>>> np.genfromtxt(data3c, dtype=None)
array([[1, 2, 3],
   [4, 5, 6]])

根据输入数据,我的相同代码可能有效,也可能无效?这听起来不对。

是的,我知道有熊猫。但我不是故意使用熊猫。所以请多多包涵。

【问题讨论】:

  • 看起来值都是整数,因此默认操作是返回常规二维数组而不是结构化数组。
  • dtype 不必有名称。例如。 dtype='i,f,i' ['i','f','i']
  • 谢谢。您是在谈论传入的 dtype 吗?问题是,我不想为 dtype 传递任何东西。至于所有整数与整数/浮点数的混合 - 如果它是混合的,似乎 numpy 会做我想要的,但如果是所有整数则不是。

标签: python numpy genfromtxt


【解决方案1】:
In [2]: txt = '''1,2,3
   ...: 4,5,6'''.splitlines()

Defaylt 二维浮点数组:

In [6]: np.genfromtxt(txt, delimiter=',',encoding=None)
Out[6]: 
array([[1., 2., 3.],
       [4., 5., 6.]])

2d 个整数:

In [7]: np.genfromtxt(txt, dtype=None, delimiter=',',encoding=None)
Out[7]: 
array([[1, 2, 3],
       [4, 5, 6]])

指定的字段数据类型:

In [8]: np.genfromtxt(txt, dtype='i,i,i', delimiter=',',encoding=None)
Out[8]: 
array([(1, 2, 3), (4, 5, 6)],
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])

指定的字段名称:

In [9]: np.genfromtxt(txt, dtype=None, delimiter=',',encoding=None, names=['a','b','c'])
Out[9]: 
array([(1, 2, 3), (4, 5, 6)],
      dtype=[('a', '<i8'), ('b', '<i8'), ('c', '<i8')])

可以将非结构化数组转换为结构化数组:

In [10]: import numpy.lib.recfunctions as rf
In [11]: rf.unstructured_to_structured(Out[7])
Out[11]: 
array([(1, 2, 3), (4, 5, 6)],
      dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8')])

numpy 中,默认的首选数组是多维数值。这就是为什么它会生成Out7]

【讨论】:

  • 谢谢。你能详细说明最后一句话吗?所以numpy 如果可以的话默认为非结构化?如果我对您的理解正确,numpy 认为如果一切都是ints,非结构化就可以了。但是如果我们混合使用floats 和ints,那么非结构化是不可能的。所以genfromtxt 自动给了我结构。对吗?
  • np.array([[1,2,3],[4,5,6]]) 产生一个 (2,3) int dtype 数组。您必须使用像 Out[11] 这样的表达式来生成结构化数组。换句话说,它必须是一个元组列表,具有完全指定的dtype
  • 谢谢。 np.genfromtxt(StringIO("1 2 3.0\n 4 5 6.0"), dtype=None) 导致带有dtype 的完全结构化数组的原因是什么?我只是想了解我什么时候需要做Out[11],因为它似乎并不总是必要的。
  • 使用dtype=None 它注意到有些列是浮点数,有些是整数。为了保持这种混合,它必须使用结构化 dtype。我之前的评论是关于使用np.array 命令(而不是通过字符串和genfromtxt)直接创建一个数组。您是否意识到结构化和非结构化数组在进行计算和索引时表现不同?不要吝啬基本的numpy 阅读。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 2021-02-08
  • 2023-04-01
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多