티스토리 뷰

DataFrame이 제공하는 함수들

(집계함수, 통계기반 함수..)

기댓값 (expected value)

  • 어떤 확률을 가진 사건을 무한히 반복했을 때, 얻을 수 있는 값의 평균으로 기대할 수 있는 값.
### 주사위 1개를 던지는 사건을 무한히 반복했을 때의 기댓값은?
import numpy as np

result = np.random.randint(1,7,(1000000,))
print(result.mean()) #  3.50021..

 

편차 (deviation)

  • 확률변수 x와 평균 (기댓값)의 차이
  • 편차를 이용하면 데이터의 흩어진 정도를 알기 쉽다.
  • 편차의 합은 0
  • 편차의 가장 큰 단점은, 데이터가 흩어진 정도를 하나의 숫자로 표현하기 힘들다는 것이다.

 

분산 (variance)

  • 데이터의 흩어진 정도를 알기 위해서 사용한다.
  • 편차의 제곱의 평균
  • 제곱을 사용해서 사용하기 애매하다..

 

표준편차 (std: standard deviation)

  • 분산의 제곱근
import numpy as np

arr = np.array([4, 6, 1, 3, 8, 8], dtype=np.int32)
print(arr)        # [4 6 1 3 8 8]
print(arr.sum())  # 30
print(arr.mean()) # 5.0
print(arr.var())  # 6.666666666666667
print(arr.std())  # 2.581988897471611

 

공분산 (covariance)

  • 두 개의 확률변수의 관계를 보여줄 때 사용하는 값
  • 공분산은, 두 확률변수의 편차의 곱에 대한 평균
  • 확률변수 X(독립변수)와 Y(종속변수)에 대해 X가 변할 때 Y가 변하는 정도.
# 그래프를 이용해서 공분산의 의미를 파악해보자

import numpy as np
import matplotlib.pyplot as plt

# 독립변수 X에 대해 종속변수 Y의 값을 랜덤으로 생성한다.
np.random.seed(1)

x = np.random.randint(-20, 20, (10, ))
y = np.random.randint(-10, 10, (10, ))

x_mean = x.mean() # X의 평균
y_mean = y.mean() # Y의 평균

# 이렇게 구한 값으로 산점도 (scatter) 그리기
plt.scatter(x, y, color='red')
plt.scatter(x_mean, y_mean, color='blue')
plt.show()

  • 공분산은 데이터 변화량에 대한 총합을 의미한다.

  • 공분산이 양수인지 음수인지에 따라 데이터의 방향성을 알 수 있다.

  • 공분산의 단점: 단위의 문제때문에, 연관성은 알 수 있지만 강도는 알 수 없다.

  • 만약 확률변수 X, Y가 독립이라면 공분산값은 0에 수렴한다.

  • 역은 성립하지 않는다. 공분산이 0이라고 두 확률변수가 독립이라고 이야기 할 수는 없다.

# 간단하게 공분산을 계산해보자.

np.random.seed(2)
sampleNum = 100   # 데이터의 개수

x = np.random.randint(0, 10,(sampleNum,))
y = np.random.randint(-20, 20,(sampleNum,))

x_mean = x.mean()  # X의 평균
y_mean = y.mean()  # Y의 평균

# 공분산은 편차의 곱의 평균
x_deviation = x - x_mean
y_deviation = y - y_mean

result = 0
for tmp in range(sampleNum):
    result += (x_deviation[tmp] * y_deviation[tmp])

result_covariance = result / (sampleNum-1)   # 표본공분산.  

print(result_covariance)
print(np.cov(x,y))

# -0.591515151515151
# [[  7.52767677  -0.59151515]
# [ -0.59151515 123.99636364]]

 

공분산을 알아보았으니 예제를 통해서 진짜로 그런지 알아보자

  • 주가를 통해 공분산의 양수, 음수 의미 알아보기

  • KOSPI 200 : 대형회사 200개의 주가로 만든 또 다른 지수

  • KOSPI 200 안에서 삼성전자의 비중이 34% 정도다

  • 삼성전자가 오르면 KOSPI가 오르고, 삼성전자가 떨어지면 KOSPI가 떨어진다.

  • 공분산으로는 두 데이터의 관계가 얼마나 강한지는 알 수 없다.

# pandas_datareader
import numpy as np
import pandas as pd
import pandas_datareader.data as pdr  # 주가 데이터를 받기 위해서 필요
from datetime import datetime         # 날짜 객체를 만들기 위해

# 특정 날짜간격동안 주식 데이터를 받아온다.
# 특정 날짜 간격을 정하기 위해 datetime을 이용하여 시작 날짜와 끝날 날짜를 지정 
start = datetime(2019, 1, 1) # 2019년 1월 1일
end = datetime(2019, 12, 31)

# YAHOO에서 제공하는 주가지수 얻어오기
df_KOSPI = pdr.DataReader('^KS11', 'yahoo', start, end)  # KOSPI
df_SE = pdr.DataReader('005930.KS', 'yahoo', start, end) # 삼성전자

display(df_KOSPI.head())  # 종가 => 'Close' column 이용
display(df_SE.head())

close_KOSPI = df_KOSPI['Close']  # Series
close_SE = df_SE['Close']        # Series

# 공분산 구하기
print(np.cov(close_KOSPI.values, close_SE.values))
# 이 값이 양수다 => 양의 관계이다. 하나가 증가하면 다른 하나도 증가하는 관계

# 공분산으로는 두 데이터의 관계가 얼마나 강한지는 알 수 없다.

import numpy as np
import pandas as pd
import pandas_datareader.data as pdr   # 주가데이터를 받기위해서 
from datetime import datetime          # 날짜객체를 만들기 위해서.

# 반대로 움직이는 주식데이터로 공분산이 음수가 되는지 확인
# 남북경협주, 방위산업주

start = datetime(2018,1,1)  # 2019년 1월 1일
end = datetime(2018,12,31)  

df_LIG = pdr.DataReader('079550.KS', 'yahoo', start, end)   # LIG넥스원(방위산업체)
df_PUSAN = pdr.DataReader('011390.KS', 'yahoo', start, end)  # 부산산업(남북경협주)

closed_LIG = df_LIG['Close']       # Series
closed_PUSAN = df_PUSAN['Close']   # Series

# 공분산 구하기
print(np.cov(closed_LIG.values, closed_PUSAN.values))  # 음수

 

상관관계, 상관계수 (피어슨 상관계수..)를 더 많이 이용한다.

  • 상관계수는 공분산을 이용해서 도출한 값이고,
  • 방향성과 두 데이터의 관련성 (연관성의 강도)도 알 수 있다.
  • 상관계수는 -1 ~ 1 사이의 실수값
  • 0 : 서로 독립
  • 1로 갈수록 양의 상관관계
  • -1로 갈수록 음의 상관관계

상관계수 (correlation coefficient)

  • 두 대상이 서로 연관성이 있다고 추측되는 관계
  • 그러나 상관관계로 인관관계를 설명할 수는 없다는 것을 조심해야 한다.
  • 인과관계는regression을 이용해서 분석해야 한다.
  • 우리가 실제로 많이 사용하는 상관계수는 (-1 ~ 1 사이의 실수)
# 상관계수 구하기
print(np.corrcoef(close_KOSPI.values, close_SE.values))

0.9 이상, 높은 상관계수

 

 

DataFrame 분석용 함수

- 중첩립스트(matrix)를 이용하여 DataFrame을 만든다

  • np.nan => NaN

sum()

  • 행 합계를 구할 때는sum(axis=1)메서드를 사용한다.
  • 열 합계를 구할 때는sum(axis=0)메서드를 사용하는데axis인수의 디폴트 값이 0이므로axis인수를 생략할 수 있다.
# DataFrame 분석용 함수
import numpy as np
import pandas as pd

# 지금까지는 DataFrame을 생성할 때 지금까지는 dictionary로 만들었다.
# 중첩립스트를 이용하여 DataFrame을 만든다 => matrix를 이용한다.
# np.nan => NaN

data = [[2, np.nan],
       [7, -3],
       [np.nan, np.nan],
       [1, -2]]

df = pd.DataFrame(data,
                 columns=['one', 'two'],
                 index=['a', 'b','c', 'd'])

display(df)

###############################################
print(df.sum()) 
# numpy일 때는 sum()에 axis를 주지 않으면 axis=None로 설정
# sum()의 대상이 ndarray 전체 요소에 적용되었다.
# DataFrame에서는 sum()을 적용하면 DataFrame의 모든 요소를 대상으로 하지 않는다.
# axis=0
# Series로 리턴된다.
# skipna = True(default)

print(df.sum(axis=1))

print(df['one'].sum())     # 특정 열에 대해 합을 구할 수 있다.

 

DaraFrame의 정렬

  • ndarray matrix의 sort와 다르다.

pandas의date_range(): 날짜 간격을 제공하는 함수

# DaraFrame의 정렬
import numpy as np
import pandas as pd

# 난수의 재현성을 확보
np.random.seed(7)

# 2차원 ndarray를 정수형 난수로 생성하고, 그 ndarray를 이용해서 DataFrame을 생성
df = pd.DataFrame(np.random.randint(0, 10, (6, 4)))
display(df)

# colum 지정
df.columns = ['A', 'B', 'C', 'D']
display(df)

# 숫자 index 대신 날짜 사용하기
df.index = pd.date_range('20200101', periods=6)
display(df)

 

Index는 다른 list나 numpy array로 '대체'하는 것이지 자체를 바꿀 수는 없다.

  • suffle()대신 permutation() 사용

  • reindex()

# 정렬 연습 하기
# index 부분 shuffle 하기

arr = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr) # shuffle은 원본이 바뀐다.
print(arr, "\n")  # [3 5 2 4 1] 

# np.random.shuffle(df.index) 
# Index does not support mutable operation 
# index는 한번 정해지면 변경되지 않는다.
# index는 다른 list나 numpy array로 '대체'하는 것이지 자체를 바꿀 수는 없다.

# index를 수정하지 않고 랜덤으로 섞은 또다른 ndarray를 리턴
random_date = np.random.permutation(df.index) 
print(" permutation() 사용")
display(random_date)

print("\n df2 사용")
df2 = df.reindex(index=random_date,columns=['B', 'A'])
display(df2)

 

인덱스 기반 정렬과 값 기반 정렬 두가지

sort_index()

  • sort_index(): index 기반 정렬
  • DataFrame에서 정렬은 두가지만 알아두자.=> axisascending
    • index 기반 정렬에서 index는 index/ column 두가지를 지칭한다.
    • 정렬된 결과 DataFrame이 return 된다.
print("===행 정렬====")
display(df2.sort_index(axis=0, ascending=True)) # 행정렬/ ascending: 내림차순, 오름차순 설정

print("\n===열 정렬====")
display(df2.sort_index(axis=1, ascending=True))  # 열정렬

sort_values()

  • sort_values(): 값으로 정렬
# 또 다른 정렬은, 값으로 정렬
display(df2.sort_values(by='B'))

# 리스트로 정렬 값 여러개 설정 => 2차 정렬
display(df2.sort_values(by=['B', 'A']))

 

DataFrame의 알아두어야 하는 기본 함수들에 대해 이야기 하고 있다.

  • sum(), mean().. 집계함수
  • 통계에 관련된 공분산, 상관계수 관련 함수들
  • 정렬에 대한 sort()
  • 3개 정도 더 알아보자
import numpy as np
import pandas as pd

np.random.seed(1)
df = pd.DataFrame(np.random.randint(0, 10, (6, 4)),
                 index=pd.date_range('20200101', periods=6),
                 columns=['A', 'B', 'C', 'D'])
df['E'] = ['AA', 'BB', 'CC', 'CC', 'AA', 'CC']

display(df)

# 중복을 없애고 unique한 값만을 추출한다.
print(df['E'].unique())
#  # ['AA' 'BB' 'CC']  # 많이 사용된다.

# 각각의 값들의 개수를 Series로 알아낼 수 있다.
print(df['E'].value_counts())

# 값이 포함되어 있는지 확인하는 함수 => boolen indexing (mask)
print(df['E'].isin(['AA', 'BB']))

apply()lambda를 이용한 처리

  • DataFrame의 유용한 함수 중, 많이 사용되지만 사용하기 쉽지 않은 것
  • apply()와lambda를 이용한 처리
import numpy as np
import pandas as pd

np.random.seed(1)
df = pd.DataFrame(np.random.randint(0, 10, (6, 4)),
                 index=pd.date_range('20200101', periods=6),
                 columns=['A', 'B', 'C', 'D'])
display(df)

# python의 lambda식
# x를 x.max() - x.min()로 대체

my_func = lambda x: x.max() - x.min()
df['최대-최소'] = df.apply(my_func, axis=1)
display(df)

print(df.apply(my_func, axis=0))

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
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
글 보관함