Data 표현

ROK·2022년 1월 5일
0

배열을 시작하기 전에 간단한 예로 숫자로 구성된 데이터를 다루는 연습을 해본다.
숫자들의 평균, 분산, 표준편차, 중앙값 등 기본 통계 데이터에 대해 생각해보자

평균 계산하기

우선 예시 코드를 보자

total = 0
count = 0
numbers = input("Enter a number : (<Enter Key> to quit)")
while number != "":
	try:
		x = float(numbers)
		count += 1
		total = total + x
	except ValueError:
		print('Not a number! Ignored..')
	numbers = input("Enter a number : (<Enter Key> to quit):)
avg = total / count
print("\n average is ", avg)

출력
Enter a number : (<Enter Key> to quit) 100
Enter a number : (<Enter Key> to quit) 200
Enter a number : (<Enter Key> to quit) 600

  average is 300.0

평균을 구하기 위해서는 숫자들의 총합이 필요할 뿐 굳이 배열 등의 변수로 저장할 필요는 없기 때문에 굳이 배열(array)로 저장하진 않았다

참고 : ∑(시그마) 시그마는 합의 기호 어떤 숫자가 나열되어 있을 때, 그 숫자들을 모두 더하는 연산을 한다면 쉽게 아래 그림과 같이 표현이 가능하다

평균의 수식을 보면 입력을 a1,a2a_1, a_2,\dots,ana_n이라 했을 때 이에 대한 평균 A는
평균

배열

배열의 의미

아래 그림은 표준 편차를 구하는 공식이다.

ss = 표준편차(std), xix_i는 입력한 숫자들, nn은 입력받은 샘플의 개수, x\overline{x}는 평균이다.
표준편차 수식을 보면 입력된 숫자에서 평균을 뺀 값이 필요하다. 지금은 입력받은 모든 숫자들을 저장해둘 필요가 있다.

각각의 숫자에 해당하는 변수를 생성해서 저장할 수도 있지만, 입력받은 숫자가 몇 개인지 모르는 상황에서 변수를 미리 생성하는 것은 불가능하다. (변수를 몇 개 생성해야 하는지 모르기 때문에)
이런 상황에서는 데이터 값 전체를 하나의 객체에 순서대로 모아 놓을 수 있어야 사용하기 편리하다

list를 이용해 간단하게 데이터를 저장할 수 있다. 리스트는 순서가 가진 요소의 배열
x1,x2,x3x_1, x_2, x_3, \dots, xnx_n을 통째로 XX라는 변수에 순서대로 저장한다.

사용자가 입력한 숫자들을 배열로 만들기

input을 통해 받은 숫자를 배열로 표현한다. 배열을 표현하기 위해 리스트(list)를 사용

def number():
	X = [] # 빈 리스트 할당
	while True:
		number = input("Enter a number (<Enter key> to quit)")
		while number !="":
			try:
				x = float(number)
				X.append(x) # float형으로 변환한 숫자 입력을 리스트에 추가
			except ValueError:
				print('>>> NOT a number! Ignored...')
			number = input("Enter a number (<Enter key> to quit):)
		if len(X) > 1:
			return X
            
X = numbers()

print('X :', X)

출력
Enter a number (<Enter key> to quit) 1
Enter a number (<Enter key> to quit) 2
Enter a number (<Enter key> to quit) 3
Enter a number (<Enter key> to quit) 4
Enter a number (<Enter key> to quit) 5
Enter a number (<Enter key> to quit) 
X : [1.0, 2.0, 3.0, 4.0, 5.0]

주석으로 설명했듯이 변수 X에 빈 리스트를 할당하여 초기화한 후 append함수를 사용해 계속 원소를 추가

C 언어의 경우 배열 변수를 만들 때 처음에 배열에 들어갈 원소의 개수를 정해놓아야 하지만 파이썬의 경우 파이썬의 리스트는 임의의 데이터 타입을 담을 수 잇는 가변적 연속열(Sequence)형으로 파이썬 리스트는 동적 배열(Dynami Array)이다.

개념 정리
계속해서 연속열(Sequence)형 데이터의 자료구조를 배열(Array)로 지칭해왔다. 하지만 정확하게 구분하자면 선형적 데이터를 다루는 자료구조인 list와 Array는 다르다.
이에 대한 참고 list와 array의 차이

list와 array의 다른 점 예시 코드

import array as arr

list = [1,2,3]		# 파이썬 built-in list
print(type[list])

list.append('4')	# list의 끝에 char '4' 추가
print(list)

list.insert(1, 5) 	# list 두 번째 자리에 5 추가
print(list)

array = arr.array('i', [1,2,3]) 	# array, import array 한 이유
print(type(array))

# 아래 코드는 실행하면 에러가 난다
# array.append('4')	# array 끝에 char '4' 추가
print(array)

array.insert(1, 5)	# array 두 번째 자리에 5 추가
print(array)

출력
<class 'list'>
[1, 2, 3, '4']
[1, 5, 2, 3, '4']
<class 'array.array'>
array('i', [1, 2, 3])
array('i', [1, 5, 2, 3])

list와 array의 차이점

  • list는 별도의 import가 필요 없지만 array를 사용하기 위해서는 import가 필요하다 (파이썬에서 array는 built-in이 아니다)
  • list 안에 요사 사이에는 다른 타입의 자료형이 허용된다(숫자 list 안에 문자열 추가 가능)
    하지만 array는 처음 생성될 때 요소의 자료형을 지정해서 생성하고, 지정되지 않은 타입의 요소는 추가가 불가능 하다. (array는 요소들이 연속된 메모리 공간에 배치되고, 모든 요소들이 동일한 크기와 타입을 가져야 한다)

리스트를 활용한 시그마의 표현

아까 처음의 숫자 배열을 다시 본다. 시그마는 입력으로 받은 숫자의 합을 total이라는 변수에 할당하였다. 아까와는 달리 배열을 사용해서 시그마를 표현한다. 시그마를 배열을 통해 계산하려면 for문을 사용해야 한다

total = 0.0
for i in range(len(X)):
	total = total + X[i]
mean = total / len(X)

print('sum of X: ', total)

출력
sum of X:  15.0 	# 위 배열에서 입력한 값 1,2,3,4,5가 그대로 사용

중앙값

중앙값은 주어진 숫자를 크기 순서대로 배치할 때 가장 중앙에 위치하는 숫자이다.
중앙이라는 위치는 그 숫자의 개수가 홀수이냐 짝수이냐에 따라 달라진다

  • 홀수 : 1,2,3,4,5,6,7이면 중앙값은 4
  • 짝수 : 1,2,3,4,5,6,7,8이면 중앙값은 (4+5)/2 = 4.5

위 예시를 수학적으로 표현하면, 총 개수가 n인 숫자들을 순서대로 배열했을 때,

  • 홀수 : n/2를 반올림한 순서(번째)의 값이 중앙값이다.
    • n = 7, 7/2 = 3.5 이므로 4번째 숫자의 값이 중앙값
  • 짝수 : n/2번째 값과 ((n/2) +1)번째 값의 평균
    • n = 8, 8/2 = 4, ((8/2)+1) = 5 이므로 4번째와 5번째의 평균이 중앙값

코드 예시

def median(nums):		# nums : 리스트를 지정하는 매개변수
	nums.sort()			# sort()로 리스트를 순서대로 정렬
	size = len(nums)
	p = size // 2
	if size % 2 == 0:	# 리스트의 개수가 짝수일 때
		pr = p			
		pl = p-1		
		mid = float((nums[pl]+nums[pr])/2)
	else:				# 리스트 개수가 홀수일 때
		mid = nums[p]
	return mid

print('X :', X)
median(X)				# 매개변수의 값으로 X를 사용함

출력
X : [1.0, 2.0, 3.0, 4.0, 5.0] 	# 앞의 입력 그대로 가져감 (리스트 X)
3.0

표준편차와 평균

평균은 간단하니 평균을 먼저 구한다 예시 코드

def means(nums):
	total = 0.0
	for i in range(len(nums)):
		total = total + nums[i]
	return total / len(nums)
    
means(X)

출력
3.0

중앙값과 동일하게 nums는 리스트를 받고 평균은 리스트의 합을 배열의 총 길이로 나눠준다.

표준편차 예시 코드

avg = means(X)

def std_dev(nums, avg):
	texp = 0.0
	for i in range(len(nums)):
   		texp = texp + (nums[i] - avg)**2	# 각 숫자와 평균값 차이의 제곱을 계속 더한 후
	return (texp / len(nums)) ** 0.5 	# 그 총합을 숫자개수로 나눈 값의 제곱근을 리턴
std_def(X.avg)

출력
1.4142135623730951
  • 매개변수로 숫자의 배열과 평균값을 받는다.
  • 각 숫자와 평균값의 차이를 구한 뒤 제곱하고, for문을 이용해 그 총합을 더한다
  • 구한 총합을 숫자의 개수로 나누고, 그 제곱근을 계산해 표준편차를 구한다.

전체 코드 : main()함수

위에 구현한 코드를 순서대로 사용한다

  • 구현하고자 하는 값은 사용자가 입력한 숫자들에 대한 평균값, 중앙값, 표준편차이다.
  • 사용자가 입력한 숫자를 배열(리스트)로 만든다
  • 각 숫자의 평균값과 중앙값을 구한다.
  • 각 숫자의 표준편차를 구한다.

지금까지의 전체 코드

def numbers():
    X=[]
    while True:
        number = input("Enter a number (<Enter key> to quit)") 
        while number !="":
            try:
                x = float(number)
                X.append(x)
            except ValueError:
                print('>>> NOT a number! Ignored..')
            number = input("Enter a number (<Enter key> to quit)")
        if len(X) > 1:
            return X

def median(nums): 
    nums.sort()
    size = len(nums)
    p = size // 2
    if size % 2 == 0:
        pr = p
        pl = p-1
        mid = float((nums[pl]+nums[pr])/2)
    else:
        mid = nums[p]
    return mid

def means(nums):
    total = 0.0
    for i in range(len(nums)):
        total = total + nums[i]
    return total / len(nums)

def std_dev(nums, avg):
   texp = 0.0
   for i in range(len(nums)):
       texp = texp + (nums[i] - avg) ** 2
   return (texp/len(nums)) ** 0.5

def main():
    X = numbers()
    med = median(X)
    avg = means(X)
    std = std_dev(X, avg)
    print("당신이 입력한 숫자{}의 ".format(X))
    print("중앙값은{}, 평균은{}, 표준편차는{}입니다.".format(med, avg, std))

if __name__ == '__main__':
    main()
profile
하루에 집중하자

0개의 댓글