새소식

데이터분석/다섯째주

EDA : Pandas(판다스)

  • -
728x90

 

Pandas DataFrame 의 구조

 

      Column Name   ↓   
Index →
 
0
1
2
3
4
      기관명            소계 2013년도이전 2014년도 2015년 2016년
강남구 3237 1292 430 584 932
강동구 1010 379 99 155 377
강북구 831 369 120 138 204
강서구 911 388 258 184 81
관악구 2109 846 260 390 613
  ← Values   
     ↑ 
  Column  
 

 

 

데이터프레임 만들기 : DataFrame( )

  pandas . DataFrame( 데이터, index=인덱스명 데이터, columns=컬럼명 데이터)  

https://pandas.pydata.org/docs/reference/frame.html

  • pandas에서 가장 많이 사용되는 데이터형은 DataFrame이다.
  • index와 columns를 지정하면 된다.
  • index와 value, column으로 이루어져 있다.
import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)
data = np.random.randn(6,4)		#표준정규분포에서 샘플링한 난수 생성

df = pd.DataFrame(data, index=dates, columns=['A', 'B', 'C', 'D'])
print(df)

-- 출력 --

 

 

import pandas as pd

# 딕셔너리 안의 리스트 형태
# 컬럼별로 데이터

df = pd.DataFrame(
	{
		'key':['K0', 'K4', 'K2', 'K3'],
		'A':['A0', 'A1', 'A2', 'A3'],
		'B':['B0', 'B1', 'B2', 'B3']
	}
)
print(df)

-- 출력 --

 

 

import pandas as pd

# 리스트 안의 딕셔너리 형태
# 행별로 데이터

df = pd.DataFrame(
	[
		{'key': 'K0', 'C': 'C0', 'D': 'D0'},
		{'key': 'K1', 'C': 'C1', 'D': 'D1'},
		{'key': 'K2', 'C': 'C2', 'D': 'D2'},
		{'key': 'K3', 'C': 'C3', 'D': 'D3'}
	]
)
print(df)

-- 출력 --

 

 

 

Series(시리즈) 만들기 : Series( )

  pandas . Seride( 데이터 )   

  pandas . Seride( 데이터, dtype=numpy.데이터 형태  또는 str )   

https://pandas.pydata.org/docs/reference/api/pandas.Series.html

  • Pandas의 데이터형을 구성하는 기본은 Series이다.
  • index와 value로 이루어져 있다.
  • 한가지 데이터 타입만 가질 수 있다.

 

import pandas ad pd
import numpy as np

s1 = pd.Series([1, 2, 3, 4])
print(s1)

s2 = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s2)

s3 = pd.Series([1, 2, 3, 4], dtype=np.float64)
print(s3)

s4 = pd.Series([1, 2, 3, 4], dtype=str)
print(s4)

s5 = pd.Series(np.array([1, 2, 3]))
print(s5)

s6 = pd.Series(np.array([1, 2, 3, '4']))
print(s6)

s7 = pd.Series({'key':'value'})
print(s7)

-- 출력 --

 

 

 

컬럼 추가 : 변수명 [ '컬럼명' ]

  DataFrame 변수명 [ '컬럼명' ] = 데이터   

  • 기존에 컬럼명이 없으면 추가, 있으면 수정이 된다.
import pandas as pd
import numpu as np

df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=['A', 'B', 'C', 'D'])
print(df)
df['E'] = ['one', 'one', 'two', 'three', 'four', 'three']
print(df)

-- 출력 --

 

 

특정 컬럼 제거 : del

  del  DataFrame 변수명 [ '컬럼명' ]   

import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)

df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=['A', 'B', 'C', 'D'])
del df['C']
print(df)

-- 출력 --

 

 

특정 컬럼 제거 : drop( )

  del  데이터프레임 변수명 . drop( [ '컬럼 또는 인덱스의 이름or순번' ],   
                                             axis=0 또는 1, inplace=True )   

  • axis :
    0이면, 가로 (행)을 삭제
    1이면, 세로 (컬럼)을 삭제

  • inplace :
    True 데이터프레임에 바로 반영한다.
    inplace 옵션을 사용하지 않으면  데이터프레임에 반영되지 않는다.
import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)

df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=['A', 'B', 'C', 'D'])
del df['C']
print(df)
df.drop(['D'], axis=1, inplace=True)
print(df)
df.drop(['20130101'], inplace=True)
print(df)
df.drop([0], axis=0, inplace=True)
print(df)

-- 출력 --

 

 

인덱스 조회 : index

  DataFrame 변수명.index   

import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)
data = np.random.randn(6,4)		#표준정규분포에서 샘플링한 난수 생성

df = pd.DataFrame(data, index=dates, columns=['A', 'B', 'C', 'D'])
print(df.index)

-- 출력 --

 

 

Column Name(컬럼명) 조회 : columns

  DataFrame 변수명.columns   

import pandas as pd
CCTV_Seoul = pd.read_csv('경로/~.csv', encoding='utf-8')

print(CCTV_Seoul.columns)
print(CCTV_Seoul.columns[0])

-- 출력 --

 

 

Column Name(컬럼명) 변경 : rename( )

  변수명.rename (columns={ '기존 컬럼명' : '컬럼명' }, inplace=True 또는 False)   

  변수명.rename (columns={ 변수명.columns[인덱스 숫자] : '컬럼명' }, inplace=True 또는 False)   

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rename.html

  • inplace :
    -  True : 데이터프레임에 바로 반영한다.
    -  inplace 옵션을 사용하지 않으면  데이터프레임에 반영되지 않는다.
import pandas as pd
CCTV_Seoul = pd.read_csv('경로/Seoul_CCTV.csv', encoding='utf-8')
print(CCTV_Seoul.columns)

CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0]: '구별'}, inplace=True)
CCTV_Seoul.head()

-- 출력 --

 

 

import pandas as pd
pop_Seoul = pd.read_excel('경로/~/Seoul_Population.xls', header=2, usecols='B, D, G, J, N')
pop_Seoul.head()

pop_Seoul.rename(
	columns={
    	pop_Seoul.columns[0]: '구별',
		pop_Seoul.columns[1]: '인구수',
		pop_Seoul.columns[2]: '한국인',
		pop_Seoul.columns[3]: '외국인',
		pop_Seoul.columns[4]: '고령자',
	},
	inplace=True
)
pop_Seoul.head()

-- 출력 --

 

 

 

 

 

< 데이터 다루기 >

날짜 / 시간 데이터 다루기 : date_range( )

  pandas . date_range( '시작 날짜', periods=날짜 수 )   

https://pandas.pydata.org/docs/reference/api/pandas.date_range.html

import pandas as pd
dates = pd.date_range('20130101', periods=6)
print(dates)

-- 출력 --

 

 

데이터 조회 : values

  DataFrame 변수명.values   

  • 리스트 형태로 반환된다.
import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)
data = np.random.randn(6,4)		#표준정규분포에서 샘플링한 난수 생성

df = pd.DataFrame(data, index=dates, columns=['A', 'B', 'C', 'D'])
print(df.values)

-- 출력 --

 

 

앞쪽 데이터 불러오기 : head( )

  DataFrame 변수명.head()   

  DataFrame 변수명.head(행수)   

  • 행수 지정이 없으면, 기본적으로 5행을 불러온다.

 

 

뒷쪽 데이터 불러오기 : tail( )

  DataFrame 변수명.tail()   

  DataFrame 변수명.tail(행수)   

  • 행수 지정이 없으면, 기본적으로 5행을 불러온다.

 

유일한 값 찾기 : unique( )

  DataFrame 변수명[ '컬럼명' ].unique()   

  • 유일한 값(즉 고유한 값)을 출력해준다.

 

유일한 값의 개수 : nunique( )

  DataFrame 변수명[ '컬럼명' ].nunique()   

  • 유일한 값(즉 고유한 값)을의 데이터 개수를 출력해준다.

 

유일한 값별로 데이터 개수 : value_counts( )

  DataFrame 변수명[ '컬럼명' ].value_counts(ascending=True 또는 False)   

 

 

 

 

< 데이터 확인 >

데이터프레임의 기본 정보 확인 : info( )

  DataFrame 변수명 . info()   

  • info() 로 각 컬럼의 크기와 데이터형태를 확인하는 경우가 많다.
  • Dtype : 데이터 형태
import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)

df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=['A', 'B', 'C', 'D'])
df.info()

-- 출력 --

 

 

데이터프레임의 통계적 개요 확인 : describe( )

  DataFrame 변수명 . describe()   

  • count : 갯수
  • mean : 평균값
  • std : 표준편차
  • min : 최소값
  • 25% : 25% 지점 값
  • 50% : 50% 지점 값
  • 75% : 75% 지점 값
  • max : 최대값
import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)

df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=['A', 'B', 'C', 'D'])
df.describe()

-- 출력 --

 

 

 

 

 

< 데이터 합치기 >

데이터 병합 : merge( )

  pandas . merge( 변수명1, 변수명2 )   

  pandas . merge( 변수명1, 변수명2,  on='기준 컬럼명' )   

  pandas . merge( 변수명1, 변수명2,  on='기준 컬럼명',   
                              how='left 또는 right 또는 outer 또는 inner' )   

  pandas . merge( 변수명1, 변수명2,  left_on='변수명1의 기준 컬럼명',   
                              right_on='변수변2의 기준 컬럼명' )   

두 데이터프레임에서 컬럼이나 인덱스를 기준으로 잡고 병합하는 방법

기준이 되는 컬럼이나 인덱스를 키값이라고 한다.

기준이 되는 키값은 두 데이터프레임에 모두 포함되어 있어야 한다.

  • 아무 옵션을 적용하지 않으면, 두 데이터의 공통 컬럼을 기준으로 inner 병합을 하게 된다.
  • on :
    키값, 데이터를 병합하는데 기준이 되는 컬럼이나 인덱스

  • how : 
    두 개의 데이터프레임을 병합하는 방법 설정
    how 옵션 설정이 없으면, 기본값은 inner 설정이다.

    -  left : 첫번째 데이터프레임의 키값을 기준으로 유지시키서 데이터를 병합한다.
    -  right : 두번째 데이터프레임의 키값을 기준으로 유지시키서 데이터를 병합한다.
    -  outer : 두 개의 데이터프레임의 키값을 모두 유지시키서 데이터를 병합한다.
    -  inner : 두 개의 데이터프레임의 키값을 공통으로 가지고 있는 데이터 기준으로 데이터를 병합한다.
    값이 없으면, NaN으로 표기한다.
import pandas as pd
import numpu as np

left = pd.DataFrame(
	{
		'key':['K0', 'K4', 'K2', 'K3'],
        'A':['A0', 'A1', 'A2', 'A3'],
        'B':['B0', 'B1', 'B2', 'B3']
	}
)

right = pd.DataFrame(
	{
		'key':['K0', 'K1', 'K2', 'K3'],
		'C':['C0', 'C1', 'C2', 'C3'],
		'D':['D0', 'D1', 'D2', 'D3']
	}
)

print(left)
print(right)
print( pd.marge(left, right, on='key') )

-- 출력 --

 

 

print(left)
print(right)
print( pd.marge(left, right, on='key', how='left') )

-- 출력 --

 

 

print(left)
print(right)
print( pd.marge(left, right, on='key', how='right') )

-- 출력 --

 

 

print(left)
print(right)
print( pd.marge(left, right, on='key', how='outer') )

-- 출력 --

 

 

print(left)
print(right)
print( pd.marge(left, right, on='key', how='inner') )

-- 출력 --

 

 

import pandas as pd

pd.set_option('display.max_columns', 10)                       # 출력할 열의 최대개수
pd.set_option('display.max_colwidth', 20)                      # 출력할 열의 너비
pd.set_option('display.unicode.east_asian_width', True)        # 유니코드 사용 너비 조정

df1 = pd.DataFrame(
	{
		'id': [128940, 130960, 138250, 139480, 142280, 145990, 185750, 192400, 199800, 204210],
		'stock_name': ['한미약품', 'CJ E&M', '엔에스쇼핑', '이마트', '녹십자엠에스', '삼양사', '종근당', '쿠쿠홀딩스', '툴젠', '모두투어리츠'],
		'value': [59385.666667, 58540.666667, 14558.666667, 239230.833333, 468.833333, 82750, 40293.666667, 179204.666667, 2514.333333, 3093.333333],
		'price': [421000, 98900, 13200, 254500, 10200, 82000, 100500, 177500, 115400, 3475]		
	}
)

df2= pd.DataFrame(
	{
		'id': [130960, 136480, 138040, 139480, 145990, 161390, 181710, 185750, 204210, 207940],
		'name': ['CJ E&M', '하림', '메리츠금융지주', '이마트', '삼양사', '한국타이어', 'NHN엔터테인먼트', '종근당', '모두투어리츠', '삼성바이오로직스'],
		'eps': [6301.333333, 274.166667, 2122.333333, 18268.166667, 5741, 5648.50, 2110.166667, 3990.333333, 85.166667, 4644.166667],
		'bps': [54068, 3551, 14894, 295780, 108090, 51341, 78434, 40684, 5335, 60099],
		'per': [15.695091, 11.489362, 6.313806, 13.931338, 14.283226, 7.453306, 30.755864, 25.185866, 40.802348, 89.790059],
		'pbr': [1.829178, 0.887074, 0.899691, 0.860437, 0.758627, 0.820007, 0.827447, 2.470259, 0.651359, 6.938551]
	}
)

print(df1)
print(df2)

-- 출력 --

 

 

result_df = pd.merge(df1, df2, how='outer', on='id')
print(result_df)

-- 출력 --

 

 

result_df = pd.merge(df1, df2, how='left', lef_on='stock_name', right_on='name')
print(result_df, '\n')

print( set(df1['stock_name'].unique()) - set(df2['name'].unique()) )	#df1에만 있는 데이터

-- 출력 --

 

 

result_df = pd.merge(df1, df2, how='right', lef_on='stock_name', right_on='name')
print(result_df, '\n')

print( set(df2['stock_name'].unique()) - set(df1['name'].unique()) )	#df2에만 있는 데이터

-- 출력 --

 

 

 

 

 

데이터 병합 : join( )

  데이터프레임 변수명 . join (변수명)   

  데이터프레임 변수명 . join (변수명, on='기준 컬럼명')   

  데이터프레임 변수명 . join (변수명1, on='기준 컬럼명',     
                                                    how='left 또는 right 또는 outer 또는 inner')   

merge( ) 함수를 기반으로 만들어져서 기본 작동방식이 비슷하다.

 join( ) 함수는 행 인덱스를 기준으로 결합하는 것 이  merge( )  함수와의 차이점이다.

  • 아무 옵션을 적용하지 않으면, 두 데이터의 공통 컬럼을 기준으로 left 병합을 하게 된다.

  • on :
    데이터를 병합하는데 기준이 되는 컬럼

  • how : 
    두 개의 데이터프레임을 병합하는 방법 설정
    how 옵션 설정이 없으면, 기본값은 left설정이다.

    -  left : 첫번째 데이터프레임의 컬럼(on 설정) 데이터를 기준으로 유지시키서 데이터를 병합한다.
    -  right : 두번째 데이터프레임의 컬럼(on 설정) 데이터를 기준으로 유지시키서 데이터를 병합한다.
    -  outer : 두 개의 데이터프레임의 컬럼(on 설정) 데이터를 모두 유지시키서 데이터를 병합한다.
    -  inner : 두 개의 데이터프레임의 컬럼(on 설정) 에 공통으로 가지고 있는 데이터 기준으로 데이터를 병합한다.
    값이 없으면, NaN으로 표기한다.
import pandas as pd

pd.set_option('display.max_columns', 10)                       # 출력할 열의 최대개수
pd.set_option('display.max_colwidth', 20)                      # 출력할 열의 너비
pd.set_option('display.unicode.east_asian_width', True)        # 유니코드 사용 너비 조정

df1 = pd.DataFrame(
	{
		'id': [128940, 130960, 138250, 139480, 142280, 145990, 185750, 192400, 199800, 204210],
		'stock_name': ['한미약품', 'CJ E&M', '엔에스쇼핑', '이마트', '녹십자엠에스', '삼양사', '종근당', '쿠쿠홀딩스', '툴젠', '모두투어리츠'],
		'value': [59385.666667, 58540.666667, 14558.666667, 239230.833333, 468.833333, 82750, 40293.666667, 179204.666667, 2514.333333, 3093.333333],
		'price': [421000, 98900, 13200, 254500, 10200, 82000, 100500, 177500, 115400, 3475]		
	}
)

df2= pd.DataFrame(
	{
		'id': [130960, 136480, 138040, 139480, 145990, 161390, 181710, 185750, 204210, 207940],
		'name': ['CJ E&M', '하림', '메리츠금융지주', '이마트', '삼양사', '한국타이어', 'NHN엔터테인먼트', '종근당', '모두투어리츠', '삼성바이오로직스'],
		'eps': [6301.333333, 274.166667, 2122.333333, 18268.166667, 5741, 5648.50, 2110.166667, 3990.333333, 85.166667, 4644.166667],
		'bps': [54068, 3551, 14894, 295780, 108090, 51341, 78434, 40684, 5335, 60099],
		'per': [15.695091, 11.489362, 6.313806, 13.931338, 14.283226, 7.453306, 30.755864, 25.185866, 40.802348, 89.790059],
		'pbr': [1.829178, 0.887074, 0.899691, 0.860437, 0.758627, 0.820007, 0.827447, 2.470259, 0.651359, 6.938551]
	}
)

print(df1)
print(df2)

-- 출력 --

 

 

df1.set_index('id', inplace=True)
df2.set_index('id', inplace=True)
print(df1)
print(df2)

-- 출력 --

 

 

result_df = df1.join(df2)
print(result_df)

-- 출력 --

 
result_df = df1.join(df2, how='inner')
print(result_df)

-- 출력 --

 

 

 

 

 

데이터 병합 : concat( )

  pandas . concat( [ 변수명1, 변수명2, ... ] , ignore_index=True, axis=0 또는 1 ,   
                               join='inner 또는 outer')   

 데이터프레임 또는 시리즈 를 물리적으로 이어 붙여주는 함수

  • ignore_index : 
    -  True : 인덱스를 재배열해준다.
    -  False : 인덱스를 그대로 유지한다. (기본값)

  • axis : 
    0이면, 가로 (행) 방향으로 데이터프레임을 이어 붙여준다. (기본값)
    1이면, 세로 (컬럼) 방향으로 데이터프레임을 이어 붙여준다.

  • join :
    데이터프레임을 병합하는 방법 설정
    -  inner : 교집합, 데이터프레임 들에 모두 존재하는 행인덱스만 이어 붙여준다.
    -  outer : 합집합, 데이터프레임 들의 모든 행인덱스를 이어 붙여준다. (기본값)

import pandas as pd
import numpu as np

df1 = pd.DataFrame(
	{		
        'A':['A0', 'A1', 'A2', 'A3'],
        'B':['B0', 'B1', 'B2', 'B3']
	}, index=[0, 1, 2, 3]
)

df2 = pd.DataFrame(
	{
		'A':['A2', 'A3', 'A4', 'A5'],
        'B':['B2', 'B3', 'B4', 'B5']
		'C':['C2', 'C3', 'C4', 'C5'],
		'D':['D2', 'D3', 'D4', 'D5']
	}, index=[2, 3, 4, 5]
)

print(df1, '\n')
print(df2)

-- 출력 --

 

 

result_df = pd.concat([df1, df2])
print(result_df)

-- 출력 --

 

 

result_df = pd.concat([df1, df2], ignore_index=True)
print(result_df)

-- 출력 --

 

 

result_df = pd.concat([df1, df2], ignore_index=True, axis=1)
print(result_df)

-- 출력 --

 

 

result_df = pd.concat([df1, df2], ignore_index=True, axis=1, join='inner')
print(result_df)

-- 출력 --

 

 

series1 = pd.Series(['e0', 'e1', 'e2', 'e3'], name='e')
series2 = pd.Series(['f0', 'f1', 'f2', 'f3'], name='f', index=[3, 4, 5])
series3 = pd.Series(['g0', 'g1', 'g2', 'g3'], name='g')
print(series1)
print(series2)
print(series3)

-- 출력 --

 

 

result_df = pd.concat([series1, series3], axis=1)
print(result_df)

-- 출력 --

 

 

result_df = pd.concat([series1, series3], axis=0)
print(result_df)

-- 출력 --

 

 

result_df = pd.concat([df1, series1], axis=1)
print(df1)
print(series1, '\n')
print(result_df)

-- 출력 --

 

 

result_df = pd.concat([df2, series2], axis=1)
print(df2)
print(series2, '\n')
print(result_df)

-- 출력 --

 

 

 

 

 

 

 

 

 

< 데이터 정렬 >

데이터프레임의 데이터 정렬 : sort_values( )

  DataFrame 변수명 . sort_values(by='기준 컬럼명', ascending=True 또는 False)   

  • by : 데이터 정렬을 한 기존이 되는 컬럼명
  • ascending : 오름차순 정렬 여부, True - 오름차순, False - 내림차순
import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)

df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=['A', 'B', 'C', 'D'])
df.sort_values(by='B', ascending=False)

-- 출력 --

 

 

열을 인덱스 지정하여 데이터 정렬  : set_index( )

  DataFrame 변수명 . set_index( '컬럼명',  inplace=True )   

  • inplace :
    - True : 데이터프레임에 바로 반영한다.
    -  inplace 옵션을 사용하지 않으면  데이터프레임에 반영되지 않는다.
  • 데이터를 정리하는 과정에서 index를 재지정할 때 사용
  • unique한 데이터를 가진 컬럼으로 index 지정
  • set_index는 인덱스 재지정하는 명령
import pandas as pd
import numpu as np

dates = pd.date_range('20130101', periods=6)

df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=['A', 'B', 'C', 'D'])
df.sort_values(by='B', ascending=False)



left = pd.DataFrame(
	{
		'key':['K0', 'K4', 'K2', 'K3'],
        'A':['A0', 'A1', 'A2', 'A3'],
        'B':['B0', 'B1', 'B2', 'B3']
	}
)

right = pd.DataFrame(
	{
		'key':['K0', 'K1', 'K2', 'K3'],
		'C':['C0', 'C1', 'C2', 'C3'],
		'D':['D0', 'D1', 'D2', 'D3']
	}
)

df = pd.marge(left, right, on='key', how='outer')
df.set_index('', inplace=True)
print(df)

-- 출력 --

 

 

 

 

 

< 데이터 분석 >

상관계수 : corr( )

  DataFrame 변수명 . corr()   

  • 상관계수가 0.2이상의 데이터를 비교하는 것은 의미가 있다.
  • 결과 데이터프레임의 대각선은 상관계수가 1이다.
  • int, float 데이터만 연산 가능하다.
import pandas as pd

-- 출력 --

 

 

 

 

 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.