통계

통계

  • 모 분산(population variance)

    • 모집단의 분산 관측값에서 모 평균을 빼고 그것을 제곱한 값을 모두 더하여 전체 데이터 수 n으로 나눔
  • 표본 분산(sample variance)

    • 표본의 분산 관측값에서 표본 평균을 빼고 제곱한 값을 모두 더한 것을 n-1로 나눔

Excel File을 python으로 바꾸기

  • 평균 구하기

  • 분산 구하기(모 분산)

  • 표준 편차 구하기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    from openpyxl import load_workbook
    from functools import reduce
    import math

    wb = load_workbook("class_1.xlsx") # 엑셀 파일을 불러옴

    ws = wb.active

    g = ws.rows

    raw_data = {}

    for name_cell, score_cell in g:
    raw_data[name_cell.value] = score_cell.value

    print(raw_data)
    >> {'greg': 95, 'john': 25, 'yang': 50, 'timothy': 15, 'melisa': 100, 'thor': 10, 'elen': 25, 'mark': 80, 'steve': 95, 'anna': 20}
    • average : 학생 평균

      1
      2
      3
      4
      5
      6
      scores = tuple(raw_data.values())

      avg = reduce(lambda a, b : a + b, scores) / len(scores)

      print(avg)
      >> 51.5
    • variance : 학생 점수 분산

      1
      2
      3
      4
      var = reduce(lambda res, x : (x - avg)**2 + res, scores) / len(scores)

      print(var)
      >> 1060.525
    • std_dev : 표준 편차

      1
      2
      3
      4
      std_dev = math.sqrt(var)

      print(std_dev)
      >> 32.56570281753489
    • evaluation : 평가

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      print("평균:{}, 분산:{}, 표준편차:{}".format(avg, var, std_dev))

      if avg < 50 and std_dev > 20:
      print('성적이 너무 저조하고 학생들의 실력 차이가 너무 크다.')

      elif avg > 50 and std_dev > 20:
      print('성적은 평균 이상이지만 학생들의 실력 차이가 크다. 주의 요망!')

      elif avg < 50 and std_dev < 20:
      print('학생들의 실력 차이는 크지 않지만 성적이 너무 저조하다. 주의 요망!')

      elif avg > 50 and std_dev < 20:
      print('성적도 평균 이상이고 학생들의 실력 차이도 크지 않다.')

      >> 평균:51.5, 분산:1060.525, 표준편차:32.56570281753489
      성적은 평균 이상이지만 학생들의 실력 차이가 크다. 주의 요망!
  • 절차 지향(procedural oriented) 프로그래밍

    • 라이브러리 개발자가 하는일

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      from openpyxl import load_workbook
      from functools import reduce
      import math

      def get_raw_data(filename):
      """
      get_raw_data(filename) -> dict
      # dict = {'name1' : score1, 'name2' : score2, 'name3' : score3 ...}
      결과값으로 딕셔너리를 반환
      """

      wb = load_workbook(filename)

      ws = wb.active

      raw_data = {}

      for name_cell, score_cell in ws.rows:
      raw_data[name_cell.value] = score_cell.value

      return raw_data
    • 래핑 함수(wrapping function)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      # 기본 기능을 감싸는 새로운 기능을 만드는 방법

      def get_scores_tuple(dict_data):
      """
      get_scores_tuple(dict) -> tuple
      dict = {'name1' : score1, 'name2' : score2, 'name3' : score3 ...}
      ret : (score1, score2, score3)
      """

      scores_data = tuple(dict_data.values())

      return scores_data
    • average : 학생 평균

      1
      2
      3
      4
      5
      6
      7
      8
      9
      def get_average(scores_data):
      """
      get_average(scores_data) -> float<2>
      scores_data --> tuple of scores
      ret : float : 소수점 이하 두 자리 반환
      """
      avg = reduce(lambda a, b: a + b, scores_data) / len(scores_data)

      return round(avg, 2) # round() : 소수점 제한 함수
    • variance : 학생 점수 분산

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      def get_variance(scores_data, avg):
      """
      get_variance(scores_data, avg) -> float<2>
      scores_data --> tuple of scores
      avg --> 평균
      ret : float : 분산 : 소수점 이하 두 자리 반환
      """

      var = reduce(lambda res, x : (x - avg)**2 + res, scores_data) / len(scores_data)

      return round(var, 2)
    • std_dev : 표준 편차

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      def get_std_dev(var):
      """
      get_std_dev(var) -> float<2>
      var --> 분산
      ret : float : 표준 편차 : 소수점 이하 두 자리 반환
      결과값으로 표준 편차 반환(소숫점 두자리까지 표시)
      """

      std_dev = math.sqrt(var)

      return round(std_dev, 2)
    • evaluation : 평가

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      def get_evaluation(avg, total_avg, std_dev, sd = 20):
      """
      get_evaluation(avg, total_avg, var, std_dev, sd = 20) -> None
      avg : your class avg
      total_avg : 학년 평균
      std_dev : 우리 반 평균
      sd : 원하는 표준 편차를 입력하세요. 20 정도면 무난합니다.
      """

      if avg < total_avg and std_dev > sd:
      print('성적이 너무 저조하고 학생들의 실력 차이가 너무 크다.')

      elif avg > total_avg and std_dev > sd:
      print('성적은 평균 이상이지만 학생들의 실력 차이가 크다. 주의 요망!')

      elif avg < total_avg and std_dev < sd:
      print('학생들의 실력 차이는 크지 않지만 성적이 너무 저조하다. 주의 요망!')

      elif avg > total_avg and std_dev < sd:
      print('성적도 평균 이상이고 학생들의 실력 차이도 크지 않다.')
    • if name ==”main”을 사용함으로서 테스트로 코드를 실행할 수 있다.

    • name == “main” 조건이 없다면 위 함수를 실행할 때마다 테스트 코드도 매번 같이 실행하게 된다.

    • name == “main”이 있음으로 해당 함수를 import로 쓰지 않고 직접 사용하게 되면 테스트 코드가 실행하게 된다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      if __name__ == "__main__":

      raw_data = get_raw_data("class_1.xlsx")
      print(raw_data)

      avg = get_average(get_scores_tuple(raw_data))
      print(avg)

      var = get_variance(get_scores_tuple(raw_data), avg)
      print(var)

      std_dev = get_std_dev(var)
      print(std_dev)

      print("평균: {}, 분산:{}, 표준편차:{}".format(avg, var, std_dev))

      get_evaluation(avg, 50, std_dev)

      >> {'greg': 95, 'john': 25, 'yang': 50, 'timothy': 15, 'melisa': 100, 'thor': 10, 'elen': 25, 'mark': 80, 'steve': 95, 'anna': 20}
      51.5
      1060.53
      32.57
      평균: 51.5, 분산:1060.53, 표준편차:32.57
      성적은 평균 이상이지만 학생들의 실력 차이가 크다. 주의 요망!
  • USER PROGRAMMER

    • 라이브러리를 사용하여 프로그램 설계

    • 하드 코딩을 하지 않도록 설계

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      import sys

      from functions import (get_raw_data, get_scores_tuple, get_average,
      get_variance, get_std_dev, get_evaluation)

      # from의 의미는 functions의 모든 코드를 다 가져다가 붙인다는 말
      # import 함수를 추가할 때 너무 길어진다면 tuple처럼 ()를 사용하여 다음 줄 이용
      # import 뒤에 *(별표)를 사용하면 해당 모듈이 모든 함수를 import한다는 뜻
      # 이렇게 되면 사용하지 않는 함수도 import하기 때문에 속도가 느려질 수 있음
      # 사용하는 함수들만 명시를 해주는 것이 좋다.

      if not len(sys.argv) == 3 and not len(sys.argv) == 4:
      print("usage : python main.py <exel filename> <total_avg> <sd = 20>")
      exit(-1)

      # exit() : 프로그램을 종료하고 싶을 때 사용.
      # 내부 숫자는 프로그램이 정상 또는 비정상적으로 종료되었다는 것을 알림

      filename = sys.argv[1]

      total_avg = float(sys.argv[2])

      if len(sys.argv) == 4:
      sd = float(sys.argv[3])

      raw_data = get_raw_data(filename)

      socres = get_scores_tuple(raw_data)

      avg = get_Average(scores)

      var = get_variance(socres, avg)

      std_dev = get_std_dev(var)

      print(f'평균 : {avg}, 분산 : {var}, 표준편차 : {std_dev}')

      if len(sys.argv) == 4:
      get_evaluation(avg, total_avg, std_dev, sd)

      elif len(sys.argv) == 3:
      get_evaluation(avg, total_avg, std_dev)

      ## visual studio code에서는 함수의 매개 변수 칸에 ctrl + shift + space를 누르면 함수 설명이 나온다.
    • sys.argv를 사용하여 직접 프로그램을 실행할 때 원하는 값 입력 가능

    • sys.argv[0]은 실행하는 소스의 이름

    • sys.argv[1]부터 지정 가능

    • sys.argv의 반환값은 모두 string 형이기 때문에 만약 숫자를 사용하고 싶다면 int와 float처럼 형변환을 해야 한다.

    • 내가 만든 라이브러리를 같은 폴더가 아니어도 불러오고 싶다면…

      1. Python / Python 37-32 / Lib / site-packages 안에 파일을 넣음

        • 개인적으로 만든 라이브러리를 넣는 것을 비추천
      2. 라이브러리를 담아두는 폴더를 만든 후에 환경 변수 경로를 지정

        • visual studio code 터미널 창에 아래와 같이 치면 된다.

        • “$env:PYTHONPATH = 경로”

        • 해당 경로는 라이브러리가 있는 폴더를 가리키면 된다.

Share