【问题标题】:Read structured data with start/end tags读取带有开始/结束标签的结构化数据
【发布时间】:2018-10-29 18:37:02
【问题描述】:

我有一个数据文件部分看起来像

START
vertex 266.36 234.594 14.6145
vertex 268.582 234.968 15.6956
vertex 267.689 232.646 15.7283
END
START
vertex 166.36 23.594 4.6145
vertex 8.582 23.968 5.6956
vertex 67.689 32.646 1.7283
END
# [...]

即三个“顶点”的块。我现在想尽快读取数据。到目前为止,我正在逐行浏览,

data = numpy.empty((n, 3))

flt = numpy.vectorize(float)
for k in range(n):
    parts = f.readline().decode('utf-8').split()
    assert len(parts) == 4
    assert parts[0] == 'vertex'
    data[k] = flt(parts[1:])

但这很慢。

有什么提示吗?

【问题讨论】:

  • loadtxt(和genfromtxt)逐行读取文件,并在列表列表中收集拆分字符串。数组最后构造一次。
  • data 初始化为 dtype float,data[k] = parts[1:] 应该可以工作。 numpy 将在赋值期间将字符串转换为浮点数。

标签: python numpy io genfromtxt


【解决方案1】:

假设您刚刚使用了 START 行,您可以尝试类似

>>> i = iter(file.__next__, 'END\n')
>>> np.loadtxt(i, usecols=(1,2,3))
array([[266.36  , 234.594 ,  14.6145],
       [268.582 , 234.968 ,  15.6956],
       [267.689 , 232.646 ,  15.7283]])

我假设loadtxt 相当快,但我不知道iter 的开销是多少。

【讨论】:

  • 我想也可以使用comments 参数来排除 START 和 END 标签。
  • @NicoSchlömer 好主意,前提是您知道如何摆脱“一些其他数据”
  • 是的,我可以单独处理。从问题中删除。
【解决方案2】:

首先,为什么需要从 utf-8 解码?您显示的数据暗示可能不需要。

想到的第二个想法是在最后一行切片数组。由于您已经检查了正好有 4 个项目,您计划跳过第一个项目,这取决于 numpy 的工作方式,因此可以选择说:

data[k] = (float(parts[1]), float(parts[2]), float(parts[3]))

【讨论】:

  • 这比flt(parts[1:])快吗?我猜不是。
  • 转换可能是因为它以通用性换取特定大小,原则上应该允许优化。但我希望放弃 utf8 的东西会带来更大的胜利。
猜你喜欢
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 2016-01-11
  • 2016-02-12
相关资源
最近更新 更多