pandas 공분산, 정렬

2021. 8. 21. 03:10python/pandas, numpy

728x90
약간 수학적인 함수


import numpy as np

arr = np.array([4,6,1,3,8,8])

print(arr.sum())   # 
print(arr.mean())  # 평균  5

편차( deviation )  :  확률변수 X와 평균의 차이
# -1    1   -4  -2  3    3
# 편차의 합은 => 0
편차의 제곱의 평균을 이용 => variance(분산)

# 1     1   16  4   9    9 
tmp = np.array([1,1,16,4,9,9])
print(tmp.mean())   # 6.666666666666667
 
print(arr.var())    # 6.666666666666667  분산

표준편차(standard deviation) : 분산의 제곱근(루트 - 분산을 구하는과정에서 제곱을했기 때문에)
print(arr.std())    # 2.581988897471611  표준편차

# 국민 개개인의 소득에 대해서 표준편차를 구해보면 => 양극화가 어떻게 진행되고 있는지를 파악

# 여기까지는 일반적인 내용

 

 


 

ex) y = 10x + 3

 x 가 변하면 y도 변한다 / 

독립변수 : x는 혼자 값이변하지만    /   종속되지 않고 값을 혼자 사용

종속변수: y는 x가 변함에 따라 종속적으로 값이 변한다 

 

# 확률변수 : X(독립변수)와 Y(종속변수)에 대해 X가 변할때 Y가 변하는 정도를 나타내는 값.

# 공분산(covariance) : 두 개의 확률변수의 관계를 보여주는 값.


arr1 = np.array([4,6,1,3,8,8])
arr2 = np.array([-1,2,7,9,10,10])

print(np.cov(arr1,arr2))   # 공분산
# 의미를 따져보자면... 양수가 나오면 독립변수가 증가하면 종속변수가 증가함을 의미
#                    음수가 나오면 독립변수가 증가하면 종속변수는 감소함을 의미
#                    이 수치의 값이 크게 의미가 없어요! /

양수와 음수로 경향을 파악할수 있다. 실제로 그 값이 크다고 뭔가를 알아낼수 있는 것이 아니라 공분산은 상대적으로 사용빈도가 적다. 단 공분산을 기반으로 다른 것이 있는데 그것을 많이 쓴다

# 공분산을 구해서 진짜 데이터가 서로 경향이 같은지를 알아보아요!

 


# 데이터가 있어야 해요!

# KOSPI , 삼성전자 데이터를 이용해서 공분산을 계산해보아요!
# 데이터가 있어야 하니...pandas의 datareader를 이용해서 이 주가데이터를 가져올 꺼예요!
# pandas_datareader module을 설치해보아요!
# pip install pandas_datareader

import numpy as np
import pandas as pd
import pandas_datareader.data as pdr
from datetime import datetime

start = datetime(2018,1,1)    # 특정날짜를 의미하는 객체를 하나 생성
end = datetime(2018,12,31)    


df_kospi = pdr.DataReader('^KS11','yahoo',start, end)    # ^KS11 : KOSPI에 대한 종목코드
df_se = pdr.DataReader('005930.KS','yahoo',start, end)    # 005930.KS : 삼성전자에 대한 종목코드

display(df_kospi)

volume 거래량 / adj close 동시호가후 최종가


# display(df_se)

df_kospi.to_json('./data/KOSPI.json')    # 파일로도 저장해 놓았어요!
df_se.to_json('./data/SE.json')          # 파일로도 저장해 놓았어요!

series_close_kospi = df_kospi['Close']    # 종가만 series로 가져온다
series_close_se = df_se['Close']

# print(series_close_kospi)

print(np.cov(series_close_kospi.values, series_close_se.values))

SE : 위에서 만든 삼성전자 값들의 변수
# 0,0 : KOSPI의 공분산
# 0,1 : KOSPI와 SE의 공분산
# 1,0 : SE와 KOSPI의 공분산 
# 1,1 : SE의 공분산

489067.36939603 이라는 공분산이 양수이므로 경향이 같다라는걸 알수있다

 


import numpy as np
import pandas as pd
import pandas_datareader.data as pdr
from datetime import datetime

start = datetime(2018,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)  # 부산산업 : 경협주(경제협력주)

series_close_lig = df_lig['Close']
series_close_pusa = df_pusan['Close']

print(np.cov(series_close_lig.values, series_close_pusa.values))

E+08은 10의8승

공분산이 음수이므로 경향이 다르다라는걸 알수있다


## 상관관계( Correlation ) : 두 대상이 서로 연관성이 있다고 추측되는 관계

# 성적과 자존감
# 온라인 게임을 하는 시간과 폭력성

 

! 공분산보다는 상관계수를 많이 사용한다
## 상관계수 (Correlation Coefficient) : -1 ~ 1 사이의 실수로 나와요!
## 0과 가까워질수록 연관성이 낮아요!
## -1이나 1로 가까워질 수록 연관성이 높아요!
## 피어슨 상관계수(상관계수의 종류중 1개로 대표적이다)

## 상관계수를 이용해서 상관관계를 분석할 때
## 조심해야 하는점이 하나 있어요!

## 인과관계(원인과 결과)는 상관계수로 설명할 수 없어요!

EX ) 연관지을수 있으나 온라인게임을 했기때문에 폭력성이 높다라고 말할수 읍다잉 ~ 


import numpy as np
import pandas as pd
import pandas_datareader.data as pdr
from datetime import datetime

start = datetime(2018,1,1)    # 특정날짜를 의미하는 객체를 하나 생성
end = datetime(2018,12,31)    

df_kospi = pdr.DataReader('^KS11','yahoo',start, end)    # ^KS11 : KOSPI에 대한 종목코드
df_se = pdr.DataReader('005930.KS','yahoo',start, end)    # 005930.KS : 삼성전자에 대한 종목코드

# display(df_kospi)
# display(df_se)

series_close_kospi = df_kospi['Close']
series_close_se = df_se['Close']

# DataFrame으로 상관계수 만들어 보아요!

df = pd.DataFrame({
    'KOSPI' : series_close_kospi.values,
    'SE' : series_close_se.values
})

display(df)


display(df.corr())

자기 자신에대해 상관계수를 구하니 1이 나온다



# numpy에서 corr대신에 corrcoef()쓰면 피어슨상관계수를 구할 수 있어요!
  numpy.corrcoef(a,b)

# 합, 평균, 편차, 분산, 표준편차, 공분산, 상관관계(계수)

 


 

# fillna의 함수에 대해서 알아보아요!

 

import numpy as np
import pandas as pd

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)


# df.sum()    ==   # df.sum(axis=0, skipna=True)   => Series가 리턴되요!

skipna=True는 nan값을 건너뛰어라


# df.sum(axis=1)

# df['two'].sum()   # -5.0
# df.loc['b'].sum()  # 4.0

# df.loc['a'].sum(skipna=False)   # nan

nan + n(수) = nan

# ?? NaN을 각 column의 평균값으로 배치해서 데이터를 완성! ㅡ> 평균다음으루 최대 최솟값을 넣는방법이 좋다
one_avg = df['one'].mean()   # 3.3333333333333335
two_avg = df['two'].mean()   # -2.5

# df['one'] = df['one'].fillna(one_avg, inplace=False)

-df['one']의 colum을 띄어온 metrix는 view이므로 원본도 변형

-fillna : nan을 찾아서 채워라

-fillna는 drop과 비슷한성향이라 원본을 바꾸던가 결과값을 리턴해야되서 inplace사용

(inplace=True는 원본을 바꾼다)

inplace=False는 결과값이 리턴되므로 위와같이


# df['two'] = df['two'].fillna(two_avg, inplace=False)

# display(df)

# df.fillna(100, inplace=True)     #df전체에도 fillna가 적용가능

# display(df)

 


DataFrame의 정렬

 



import numpy as np
import pandas as pd

np.random.seed(1)

df = pd.DataFrame(np.random.randint(0,10,(6,4)))

# display(df)


df.columns = ['A', 'B', 'C', 'D']
df.index = pd.date_range('20210801', periods=6)  #periods : 몇일이냐

# display(df)


# numpy할 때 random하게 섞는 함수 기억나나요?  => shuffle()    np.random.shuffle()
# shuffle은 원본을 랜덤하게 섞어요..다시말해서 랜덤하게 섞은 결과를 리턴하지 않아요!
# 그래서 shuffle()은 immutable한 index같은거에서는 적용할 수 없어요! => 다른거 써야해요!

# np.random.shuffle(df.index)  # Index does not support mutable operations

# df의 index(row, colum)은 원본을 random을 섞을수가 없어 reindex를 이용
randome_date = np.random.permutation(df.index)

#permutation을 이용하면 섞은다음에 원본은 그대로 복사본을 만든다

 


# df.index = randome_date  # 이렇게 하는거 아니예요..

(위 사진과 비교해보면 index만 바뀌고 값은 그대로라 ..)



new_df = df.reindex(index=randome_date, columns=['B','A','D','C'])

# reindex를 이용하면np.random.permutation사용시 값도 자동으로 바뀐다

# 당연히 copy 이며 colum도 자리를 바꿀수 있다

display(new_df)

index를 기반으로 한 정렬
# sort_df = new_df.sort_index(axis=0, ascending=True)

.sort_index : 정렬  /  ascending=True 오름차순(작은게 위) = 진짜
# sort_df = new_df.sort_index(axis=1, ascending=True)
# display(sort_df)

# 특정 column의 값을 기준으로 정렬
# sort_df = new_df.sort_values(by='D')

# (by=)는 어떤 colum의 값을 기준으로 할꺼냐

default는 오름차순


sort_df = new_df.sort_values(by=['A','D'])
#A를 기준으로 정렬하고 값이 곂친다면 D를 기준으로
display(sort_df)


 



# 새로운 column을 하나 추가해 보아요!

 

df['E'] = ['AA', 'BB', 'CC', 'CC', 'AA', 'CC']

# display(df)


# df['E'].unique()   # 중복을 배제!!!!                   # unique - 고유한

 


df['E'].value_counts()   # 각 값들의 개수를 Series로 리턴



df['E'].isin(['AA', 'BB']) # boolean mask가 만들어져요! 

어떠한 값이 안에 있니 ?

 


# df['학과'].isin(['철학', '컴퓨터'])   철학과와 컴퓨터학과를 추출하기 위한 boolean mask를 생성할 수 있어요!

# 다음시간에는 DataFrame 간의 결합(merge), Grouping에 대해서 설명하고
# => 수행평가문제를 해결하면서 배운내용을 복습해보아요!

 

'python > pandas, numpy' 카테고리의 다른 글

pandas concat(연결), 결측치, 이상치, 중복행  (0) 2021.08.23
pandas merge (feat. join)  (0) 2021.08.23
pandas 인덱스 와 컬럼(index & colum)  (0) 2021.08.20
dataframe으로 json이용  (0) 2021.08.19
pandas 기초  (0) 2021.08.19