Библиотека Numpy предоставляет функции для расчета простых статистик: среднее значение, медиана, стандартное отклонение и т.п. Вопросу использования данных функций посвящен этот урок.
- Введение
- Размерность массива
- Общие правила при работе с массивами Numpy
-
- Вызов функции расчета статистики
- Расчет статистик по строкам или столбцам массива
-
- Функции (методы) для расчета статистик в Numpy
Введение
Импортируйте библиотеку Numpy, если вы еще этого не сделали.
>>> import numpy as np
Для начала создадим матрицу, которая нам понадобится в работе.
>>> m = np.matrix('1 2 3 4; 5 6 7 8; 9 1 5 7') >>> print(m) [[1 2 3 4] [5 6 7 8] [9 1 5 7]]
В этом случае будет создан объект типа matrix.
>>> type(m) <class 'numpy.matrixlib.defmatrix.matrix'>
Если вы уже работали с Numpy, это может для вас быть чем-то новым. В Numpy, как правило, приходится работать с объектами класса ndarray. Мы выбрали matrix из-за удобства объявления массива, т.к. matrix позволяет использование Matlab-подобный стиль, и, наверное, вам будет интересно познакомиться с чем-то новым. Для задач, рассматриваемых в рамках данной статьи, объекты matrix и ndarray одинаково хорошо подходят. Matix можно превратить в ndarray вот так:
>>> m = np.array(m) >>> type(m) <class 'numpy.ndarray'>
В любом случае наша таблица чисел будет выглядеть следующим образом.
Размерность массива
Для определения размерности массива Numpy используйте атрибут shape.
>>> m.shape (3, 4)
В результате мы получим кортеж из двух элементов, первый из них – это количество строк, второй – столбцов.
Перед тем, как перейти к описанию функций расчета статистик необходимо, чтобы вы запомнили несколько важных вещей, касательно функций и массивов Numpy.
Вызов функции расчета статистики
Для расчета той или иной статистики, соответствующую функцию можно вызвать как метод объекта, с которым вы работаете. Для нашего массива это будет выглядеть так.
>>> m.max() 9
Тот же результат можно получить вызвав библиотечную функцию с соответствующим именем, передав ей в качестве аргумента массив.
>>> np.max(m) 9
Расчет статистик по строкам или столбцам массива
Вызовем функцию вычисления статистики (максимальный элемент) без аргументов.
>>> m.max() 9
В этом случает будут обработаны все элементы массива.
Если необходимо найти максимальный элемент в каждой строке, то для этого нужно передать в качестве аргумента параметр axis=1.
>>> m.max(axis=1) matrix([[4], [8], [9]])
Для вычисления статистики по столбцам, передайте в качестве параметра аргумент axis=0.
>>> m.max(axis=0) matrix([[9, 6, 7, 8]])
Функции (методы) для расчета статистик в Numpy
Ниже, в таблице, приведены методы объекта ndarray (или matrix), которые, как мы помним из раздела выше, могут быть также вызваны как функции библиотеки Numpy, для расчета статистик по данным массива.
Имя метода | Описание |
argmax | Индексы элементов с максимальным значением (по осям) |
argmin | Индексы элементов с минимальным значением (по осям) |
max | Максимальные значения элементов (по осям) |
min | Минимальные значения элементов (по осям) |
mean | Средние значения элементов (по осям) |
prod | Произведение всех элементов (по осям) |
std | Стандартное отклонение (по осям) |
sum | Сумма всех элементов (по осям) |
var | Дисперсия (по осям) |
Вычислим некоторые из представленных выше статистик.
>>> m.mean() 4.833333333333333 >>> m.mean(axis=1) matrix([[2.5], [6.5], [5.5]]) >>> m.sum() 58 >>> m.sum(axis=0) matrix([[15, 9, 15, 19]])
P.S.
Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. На нашем сайте вы можете найти вводные уроки по этой теме. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.
<<<Библиотека Numpy. Использование boolean массива для доступа к ndarray — Библиотека numpy. Работа с массивами. Слайсы>>>
Я тут начеркал кое что, вот главный файл
from funck import fucnks
massGroup = [
dict(Иванов=[3, 4, 5], Петров=[5, 5, 5], Дубовская=[4, 4, 5]),
dict(Пеньков=[4, 5, 3], Деревко=[2, 5, 4], Осинова=[4, 3, 5]),
dict(Кузнецов=[4, 3, 2], Молотков=[3, 5, 3], Берёзин=[5, 5, 5], Клёнова=[3, 4, 5])
]
def averageCalculation(group):
keys = fucnks.getKeys(group) # получаем ключи из словаря
massForAssessment = [] # массив куда сохраняются оценки всех учеников
while True:
lenMass = len(keys) # получение длинны массива, для перебора
for i in range(lenMass):
name = str(keys[i]) # получаем ключ
getName = group[name] # достаём значение по ключу
lenMassForAssessment = len(getName)
for i in range(lenMassForAssessment):
massForAssessment.append(int(getName[i])) # добавляем в массив оценку
break
summa = fucnks.addingElementsInAnArray(massForAssessment) # получаем сумму оценок
mid = str(summa / len(massForAssessment)) # получаем среднее значение
print(mid[0:4]) # выводим
def main():
for i in range(len(massGroup)):
print(massGroup[i])
averageCalculation(massGroup[i])
main()
тут файл функций
class fucnks:
def addingElementsInAnArray(array):
lengArray = len(array)
summa = 0
for i in range(lengArray):
summa += array[i]
return summa
def getKeys(group):
return [i for i in group]
вот вывод:
{'Иванов': [3, 4, 5], 'Петров': [5, 5, 5], 'Дубовская': [4, 4, 5]}
> 4.44
{'Пеньков': [4, 5, 3], 'Деревко': [2, 5, 4], 'Осинова': [4, 3, 5]}
> 3.88
{'Кузнецов': [4, 3, 2], 'Молотков': [3, 5, 3], 'Берёзин': [5, 5, 5], 'Клёнова': [3, 4, 5]}
> 3.91
Задание я не совсем чётко понял, если есть замечание пишите в комментарии я перепишу код
You will see that this answer actually would fit better to your other question that was marked as duplicated to this one (and don’t know why because it is not the same question…)
The presence of zeros can indeed affect the columns’ or rows’ average, for instance:
a = np.array([[ 0, 1, 0.9, 1],
[0.9, 0, 1, 1],
[ 1, 1, 0, 0.5]])
Without eliminating the diagonals, it would tell that the column 3
has the highest average, but eliminating the diagonals the highest average belongs to column 1
and now column 3
has the least average of all columns!
You can correct the calculated mean using the lcm
(least common multiple) of the number of lines with and without the diagonals, by guaranteeing that where a diagonal element does not exist the correction is not applied:
correction = column_sum/lcm(len(column), len(column)-1)
new_mean = mean + correction
I copied the algorithm for lcm
from this answer and proposed a solution for your case:
import numpy as np
def gcd(a, b):
"""Return greatest common divisor using Euclid's Algorithm."""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""Return lowest common multiple."""
return a * b // gcd(a, b)
def mymean(a):
if len(a.diagonal()) < a.shape[1]:
tmp = np.hstack((a.diagonal()*0+1,0))
else:
tmp = a.diagonal()*0+1
return np.mean(a, axis=0) + np.sum(a,axis=0)*tmp/lcm(a.shape[0],a.shape[0]-1)
Testing with the a
given above:
mymean(a)
#array([ 0.95 , 1. , 0.95 , 0.83333333])
With another example:
b = np.array([[ 0, 1, 0.9, 0],
[0.9, 0, 1, 1],
[ 1, 1, 0, 0.5],
[0.9, 0.2, 1, 0],
[ 1, 1, 0.7, 0.5]])
mymean(b)
#array([ 0.95, 0.8 , 0.9 , 0.5 ])
With the corrected average you just use np.argmax()
to get the column index with the highest average. Similarly, np.argmin()
to get the index of the column with the least average:
np.argmin(mymean(a))
You will see that this answer actually would fit better to your other question that was marked as duplicated to this one (and don’t know why because it is not the same question…)
The presence of zeros can indeed affect the columns’ or rows’ average, for instance:
a = np.array([[ 0, 1, 0.9, 1],
[0.9, 0, 1, 1],
[ 1, 1, 0, 0.5]])
Without eliminating the diagonals, it would tell that the column 3
has the highest average, but eliminating the diagonals the highest average belongs to column 1
and now column 3
has the least average of all columns!
You can correct the calculated mean using the lcm
(least common multiple) of the number of lines with and without the diagonals, by guaranteeing that where a diagonal element does not exist the correction is not applied:
correction = column_sum/lcm(len(column), len(column)-1)
new_mean = mean + correction
I copied the algorithm for lcm
from this answer and proposed a solution for your case:
import numpy as np
def gcd(a, b):
"""Return greatest common divisor using Euclid's Algorithm."""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""Return lowest common multiple."""
return a * b // gcd(a, b)
def mymean(a):
if len(a.diagonal()) < a.shape[1]:
tmp = np.hstack((a.diagonal()*0+1,0))
else:
tmp = a.diagonal()*0+1
return np.mean(a, axis=0) + np.sum(a,axis=0)*tmp/lcm(a.shape[0],a.shape[0]-1)
Testing with the a
given above:
mymean(a)
#array([ 0.95 , 1. , 0.95 , 0.83333333])
With another example:
b = np.array([[ 0, 1, 0.9, 0],
[0.9, 0, 1, 1],
[ 1, 1, 0, 0.5],
[0.9, 0.2, 1, 0],
[ 1, 1, 0.7, 0.5]])
mymean(b)
#array([ 0.95, 0.8 , 0.9 , 0.5 ])
With the corrected average you just use np.argmax()
to get the column index with the highest average. Similarly, np.argmin()
to get the index of the column with the least average:
np.argmin(mymean(a))
UPDATED QUESTION AND CODE!30.01.2021
This question logically came up after this question — How to find a separate attribute among the records and form a separate collection on it?
I need to calculate the average score of each group.
In the code that the user @itprorh66 suggested, I added a formula for calculating the average score(it works) and a conditional search operator for the grade.
Mister @itprorh66
I decided to modify your code a bit to try to solve my problem myself. But so far unsuccessful.
This code block is working
def srtgr(self):
counthrees=0
countfours=0
countfives=0
midl_average=0
gl=dict() #Dictionary for the group
for s in studinfos:
sd=gl.pop(s.numbgroup,dict())
sd[s.surn]=[s.markgeometry,s.markalgebra,s.markinformatika]
gl[s.numbgroup]=sd
for k,v, in gl.items():
s=f'Group: {k}: n'
for stdn,grds in v.items():
s+=f' {stdn}t{grds[0]},{grds[1]},{grds[2]} n'
print(s)
This is the second part in def srtgr
. In this code block I trying to calculate the number of grades (3,4 and 5) in each group, and then find the average grade for each group. With the help of a loop, I start traversing the dictionary and with the help of the branch operator I start counting the scores in each group, but that’s what I thought when I wrote this code. In reality, nothing starts and does not count
for grds in gl.items():
if grds.markgeometry==3:
counthrees+=1
if grds.markalgebra==3:
counthrees+=1
if grds.markinformatika==3:
counthrees+=1
if grds.markgeometry==4:
countfours+=1
if grds.markalgebra==4:
countfours+=1
if grds.markinformatika==4:
countfours+=1
if grds.markgeometry==5:
countfives+=1
if grds.markalgebra==5:
countfives+=1
if grds.markinformatika==5:
countfives+=1
midl_average = (counthrees+countfours+countfives)/3
for kk,grds1 in gl.items():
grds=f'Group: {kk}: {grds1}n'
print(grds)
print(*sorted(gl, key = midl_average, reverse = True))
INPUT DATA
My reputation is litlle and I can not add the picture form my computer and I send the link,where my input data, what I add in class and how my object classes collection showing in the console. And the separated of groups
How to make it so that the average grade is displayed at the bottom after the list of students in each group?
Or just calculate the average score in each group and enter it into another dictionary?
I figured out the sorting of values in the dictionary.
I tried to make a 2nd dictionary and put the groups there, and then calculate it in a separate assessment unit — it didn’t work.
Then I read that in Python you can add a dictionary to a dictionary.
As a result, I tried to add the existing dictionary to the new one, but did not understand how to proceed.
Because grades must be calculated anyway
You cannot use any helper classes, work with only one class.
UPDATED QUESTION AND CODE!30.01.2021
This question logically came up after this question — How to find a separate attribute among the records and form a separate collection on it?
I need to calculate the average score of each group.
In the code that the user @itprorh66 suggested, I added a formula for calculating the average score(it works) and a conditional search operator for the grade.
Mister @itprorh66
I decided to modify your code a bit to try to solve my problem myself. But so far unsuccessful.
This code block is working
def srtgr(self):
counthrees=0
countfours=0
countfives=0
midl_average=0
gl=dict() #Dictionary for the group
for s in studinfos:
sd=gl.pop(s.numbgroup,dict())
sd[s.surn]=[s.markgeometry,s.markalgebra,s.markinformatika]
gl[s.numbgroup]=sd
for k,v, in gl.items():
s=f'Group: {k}: n'
for stdn,grds in v.items():
s+=f' {stdn}t{grds[0]},{grds[1]},{grds[2]} n'
print(s)
This is the second part in def srtgr
. In this code block I trying to calculate the number of grades (3,4 and 5) in each group, and then find the average grade for each group. With the help of a loop, I start traversing the dictionary and with the help of the branch operator I start counting the scores in each group, but that’s what I thought when I wrote this code. In reality, nothing starts and does not count
for grds in gl.items():
if grds.markgeometry==3:
counthrees+=1
if grds.markalgebra==3:
counthrees+=1
if grds.markinformatika==3:
counthrees+=1
if grds.markgeometry==4:
countfours+=1
if grds.markalgebra==4:
countfours+=1
if grds.markinformatika==4:
countfours+=1
if grds.markgeometry==5:
countfives+=1
if grds.markalgebra==5:
countfives+=1
if grds.markinformatika==5:
countfives+=1
midl_average = (counthrees+countfours+countfives)/3
for kk,grds1 in gl.items():
grds=f'Group: {kk}: {grds1}n'
print(grds)
print(*sorted(gl, key = midl_average, reverse = True))
INPUT DATA
My reputation is litlle and I can not add the picture form my computer and I send the link,where my input data, what I add in class and how my object classes collection showing in the console. And the separated of groups
How to make it so that the average grade is displayed at the bottom after the list of students in each group?
Or just calculate the average score in each group and enter it into another dictionary?
I figured out the sorting of values in the dictionary.
I tried to make a 2nd dictionary and put the groups there, and then calculate it in a separate assessment unit — it didn’t work.
Then I read that in Python you can add a dictionary to a dictionary.
As a result, I tried to add the existing dictionary to the new one, but did not understand how to proceed.
Because grades must be calculated anyway
You cannot use any helper classes, work with only one class.
#include <stdio.h></stdio.h> #include <stdlib.h></stdlib.h> #define SIZE 25 int main() { char *groups[] = { "Gr_1", "Gr_2", "Gr_3" }; char *exams[] = { "Ex_1", "Ex_2", "Ex_3", "Ex_4" }; char balls[sizeof(groups)/sizeof(char*)][sizeof(exams)/sizeof(char*)][SIZE]; int i, u; double tmp; char *ptr = (char*) balls; for (i=0; i<(SIZE*(sizeof(groups)/sizeof(char*))*(sizeof(exams)/sizeof(char*))); ++i, ++ptr){ *ptr = (rand() % 4 + 1); } ptr = (char*) balls; for (u=0, tmp=0; u<(sizeof(groups)/sizeof(char*)); ++u, tmp=0) { for (i=0; i<(SIZE*(sizeof(exams)/sizeof(char*))); ++i, ++ptr){ tmp += *ptr; } printf("группа '%s' средний бал %fn", groups[u], tmp/(SIZE*(sizeof(exams)/sizeof(char*))) ); } return 0; }