将numpy recarray的(一部分)转换为2d数组?

4

我们有一组关于各个日期的记录数据,其中第一个属性是时间戳,其余属性是数值。

其中几个为:

    ts             a    b    c
2010-08-06 08:00, 1.2, 3.4, 5.6
2010-08-06 08:05, 1.2, 3.4, 5.6
2010-08-06 08:10, 1.2, 3.4, 5.6
2010-08-06 08:15, 2.2, 3.3, 5.6
2010-08-06 08:20, 1.2, 3.4, 5.6

我们希望生成每个值的平均数组(就像您将所有日期数据叠放在一起,并对齐所有值进行平均一样)。时间戳时间全部匹配,因此我们可以通过创建一个带有时间戳和其他列全部为0的结果记录数组来完成,然后执行以下操作:

for day in day_data:
    result.a += day.a
    result.b += day.b
    result.c += day.c

result.a /= len(day_data)
result.b /= len(day_data)
result.c /= len(day_data)

看起来更好的方法是将每天转换为一个只包含数字的二维数组(去掉时间戳),然后在一个操作中逐元素地对它们进行平均,但我们找不到这样做的方法——它总是一个对象的一维数组。

有谁知道如何做到这点吗?

1个回答

8

有几种方法可以实现这一点。其中一种方法是选择recarray的多个列并将它们转换为浮点数,然后重新整形为2D数组:

new_data = data[['a','b','c']].astype(np.float).reshape((data.size, 3))

另外,您可以考虑使用以下代码(速度略慢,但更易于阅读):
new_data = np.vstack([data[item] for item in ['a','b','c']]).T

请注意,研究 pandas 可能是一个不错的主意,因为它可以让您轻松处理异构数据等操作。


2
太好了,谢谢!我仍然在努力适应整体数组操作 - 我的本能是逐个元素进行操作。从我的测试中得出一个注意点 - 虽然 .view(np.float) 部分不会复制,但花式切片会复制。 - babbageclunk
1
@Joe:如果我没记错的话,@wilberforce关于复制的说法是正确的:data[['a','b','c']].base为None,这意味着它拥有自己的数据,而不是从data继承。这很有道理,因为这些字段通常不是连续的。如果你确认了这一点,更新你的答案会很好。 :) - Eric O. Lebigot
@EOL - 你说得完全正确!(我当时在想什么呢...) - Joe Kington
1
@EOL - 此外,使用类似于data[['a', 'b', 'c']]的结构化数组索引将在未来版本的numpy中返回视图:https://github.com/numpy/numpy/pull/350/files。正如您所提到的,目前它并没有这样做,过去也没有。 - Joe Kington

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接