一尘不染

块均值结构化数组

python

假设我有一个结构化的学生(字符串)和测验分数(整数)数组,其中每个条目都是特定学生在特定测验中获得的分数。每个学生自然都有这个数组中的多个条目。

import numpy
grades = numpy.array([('Mary', 96), ('John', 94), ('Mary', 88), ('Edgar', 89), ('John', 84)],
                     dtype=[('student', 'a50'), ('score', 'i')])

print grades
#[('Mary', 96) ('John', 94) ('Mary', 88) ('Edgar', 89) ('John', 84)]

如何轻松计算每个学生的平均分数?换句话说,我该如何在“得分”维度中采用数组的均值?我想做

grades.mean('score')

并有脾气暴躁的回报

[('Mary', 92), ('John', 89), ('Edgar', 89)]

但是Numpy抱怨

TypeError: an integer is required

有一个简单的方法可以轻松做到这一点吗?我认为这可能涉及使用具有不同dtype的结构化数组的视图。任何帮助,将不胜感激。谢谢。

编辑

>>> grades = numpy.zeros(5, dtype=[('student', 'a50'), ('score', 'i'), ('testid', 'i'])
>>> grades[0] = ('Mary', 96, 1)
>>> grades[1] = ('John', 94, 1)
>>> grades[2] = ('Mary', 88, 2)
>>> grades[3] = ('Edgar', 89, 1)
>>> grades[4] = ('John', 84, 2)
>>> np.mean(grades, 'testid')
TypeError: an integer is required

阅读 193

收藏
2021-01-20

共1个答案

一尘不染

NumPy并非旨在将行分组在一起并将聚合函数应用于这些组。你可以:

  • 使用itertools.groupby和重建数组;
  • 使用基于NumPy且擅长分组的Pandas;要么
  • 在测试ID的数组中添加另一个维度(因此,本例将是2x3数组,因为看起来好像有两个测试)。

这是itertools解决方案,但是您可以看到它非常复杂且效率低下。我建议其他两种方法之一。

np.array([(k, np.array(list(g), dtype=grades.dtype).view(np.recarray)['score'].mean())
          for k, g in groupby(np.sort(grades, order='student').view(np.recarray),
                              itemgetter('student'))], dtype=grades.dtype)
2021-01-20