【问题标题】:Variable/unknown length string/unicode dtype in numpynumpy中的可变/未知长度字符串/ unicode dtype
【发布时间】:2014-01-05 22:20:10
【问题描述】:

是否可以以某种方式加载具有未知字段长度的文本字段的数组?

我想出了如何通过dtype 来获取字符串。但是,如果没有指定长度,我只会得到U0。似乎无法保存任何数据的类型。例如:

data = io.StringIO("test data lololol\ntest2 d4t4 ololol")
>>> ar = numpy.loadtxt(data, dtype=[("1",str), ("2",'S'), ("3",'S')])
>>> ar
array([('', b'', b''), ('', b'', b'')], 
      dtype=[('1', '<U0'), ('2', '|S0'), ('3', '|S0')])

当我更改为指定大小的模式时,我得到输入:

>>> data.seek(0)
0
>>> numpy.loadtxt(data, dtype=[("1",(str,30)), ("2",(str,30)), ("3",('S',30))])
array([("b'test'", "b'data'", b'lololol'),
       ("b'test2'", "b'd4t4'", b'ololol')], 
      dtype=[('1', '<U30'), ('2', '<U30'), ('3', '|S30')])

SU 可能都可以。在我的案例中,该字段应该用于保存一组文本标志。类似于linux环境变量的东西。因此,为了以防万一而预先分配大空间似乎是一种很大的浪费。尤其是当行数达到数百万时。

我确实了解或有想法,这样的设计可以来自哪里。就像构造一个 struct 之类的对象,它将整行保存在连续的内存块中。但是,我想也许有办法让它在字符串的情况下像指针一样保持。

有可能吗?

【问题讨论】:

  • 不是 numpy 适合的任务。例如,您可以使用 hash 函数对字符串进行编码(即手动构造指针),并将主题存储在其他地方。

标签: python python-3.x numpy


【解决方案1】:

getting indices in numpy 使用np.recfromtxt,可以自动生成dtype。实际上,它使用dtype=None 调用np.genfromtxt

类似的数据:

david weight_2005 50
david weight_2012 60
david height_2005 150
david height_2012 160

产生一个:

array([('david', 'weight_2005', 50), ('david', 'weight_2012', 60),
       ('david', 'height_2005', 150), ('david', 'height_2012', 160),...], 
      dtype=[('f0', 'S5'), ('f1', 'S11'), ('f2', '<i4')])

genfromtxt 中用于确定dtype 的代码看起来很复杂。我猜它会调整 Snn 以适应它在该字段中遇到的最长字符串。

自定义dtype 的一种方法是在getnfromtxt 中分配names,然后用astype 重铸这些值。

x=np.genfromtxt('stack19944408.txt',dtype=None,names=['one','two','thr'])
x.astype(dtype=[('one','S10'),('two','S10'),('thr','f')])
#array([('david', 'weight_200', 50.0), ('david', 'weight_201', 60.0),
#       ...
#      dtype=[('one', 'S10'), ('two', 'S10'), ('thr', '<f4')])

【讨论】:

  • 我看到没有简单的解决方案。您的解决方案有点工作,但就像我害怕一样,它需要预先分配空间,而不管实际数据如何。我的问题是该字段的长度可以从 10100 字符长,这适用于 10^6 到 10^8 行。这就是为什么我不喜欢它。我接受了您的解决方案,因为对于较小的数据集,它可能没问题并且可以自动工作,我喜欢。我亲自将标志编码为二进制,并提供str &lt;=&gt; uint 字典映射以供以后解码。这样我就有了一些额外的工作,但节省了很多空间。
  • 所以您担心如果genfromtxt 选择S100 来容纳您最长的记录字段,那么其他记录中会出现很多空白吗?我认为如果字符串存储在数组本身(具有恒定的记录大小)中,情况就必须如此。另一种选择是objectdtype,字符串存储为常规 Python 字符串(并且只是数组中的指针)。
猜你喜欢
  • 1970-01-01
  • 2012-02-24
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多