Вопрос по python, numpy, mean, recarray – Структурированный массив Numpy Mean

4

Предположим, что у меня есть структурированный массив студентов (строки) и результатов тестов (целых), где каждая запись - это результат, полученный конкретным студентом в ходе определенного теста. Естественно, у каждого ученика есть несколько записей в этом массиве.

Example

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')

и вернуть Numpy

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

но Numpy жалуется

TypeError: an integer is required

Есть ли Numpy-esque способ сделать это легко? Я думаю, что это может включать просмотр структурированного массива с другим dtype. Любая помощь будет оценена. Благодарю.

Edit

>>> 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

Ваш Ответ

4   ответа
1

0

itertools, без использования view (), есть

[(k,e['score'][list(g)].mean()) for k, g in groupby(argsort(e),e['student'].__getitem__ )]

Это та же идея ecatmur, но она работает в терминах индексов, использующих argsort () вместо sort.

0

def collapseByField(e,collapsefield,keepFields=None,agg=None):
   import numpy as np
   assert isinstance(e,np.ndarray) # Structured array
   if agg is None:
       agg=np.mean
   if keepFields is None:
       newf=[(n,agg,n) for n in e.dtype.names if n not in (collapsefield)]
   import matplotlib as mpl
   return(mpl.mlab.rec_groupby(e,[collapsefield],newf))
4

чтобы иметь возможность группировать строки и применять агрегатные функции к этим группам. Вы могли бы:

use itertools.groupby and reconstruct the array; use Pandas, which is based on NumPy and is great at grouping; or add another dimension to the array for the test id (so this case would be a 2x3 array, because it looks like there were two tests).

Здесь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)
@ Джереми дополнительное измерение для идентификатора теста. Таким образом, для 3 студентов и 2 тестов у вас есть массив 2х3.
Смотрите мое редактирование. Я получаю TypeError, когда я пытаюсь это сделать. Jeremy
Я не понимаю, как может помочь добавление другого измерения. Jeremy
@ Джереми, тогда ты можешь позвонитьnp.mean(axis=1) над осью test-id.
Правильно. Так получилось, что в моей программе уже есть измерение testid. Как это поможет мне? Jeremy

Похожие вопросы