**본 내용은 Alice 의 데이터 분석을 위한 라이브러리 과정을 수강하면서 , 직접 궁금한 것을 찾아보고 공부하며 정리한 내용임.
1. 데이터 핸들링을 위한 라이브러리 Numpy
Numpy 란? : Numerical Python
대규모 다차원 배열을 다룰수 있게 도와주는 python 라이브러리 'NumPy'
-
사용이유?
- 데이터의 대부분 숫자 배열로 볼수 있다. (객체로 고차원 배열 제공, 관련된 메소드 제공)
- 반복문 없이 배열 처리 가능
- 리스트에 비해 빠른 연산 지원, 메모리 효율적 사용 (연산의 벡터화)
- 수많은 수학 연산을 기본 제공
- 다른 패키지에서도 Numpy 배열을 기초 자료형으로 사용
사용 어떻게?
- 1. list 배열 생성 및 출력 형태 확인
list_arr = list(range(5)) #[0,1,2,3,4] - 콤마로 구분!
print(type(list_arr)) #<class'list'>
- 2. numpy 배열 생성 및 출력 형태 확인
ndarray = n차원의 배열 (n-dimensional array)
import numpy as np
np_arr = np.array(range(5))
pritn(np_arr) #[0 1 2 3 4] - 공백으로 구분! - list는 콤마!
print(type(np_arr)) #<class 'numpy.ndarray'> - 클래스의 타입은 ndarray이다.
np.linspace(0, 10, 5) # 0과 10 사이 5개의 요소를 가지는 array 생성,
# 요소 개수는 default가 50
# restep옵션으로 간격확인 가능
** arange 함수는 일정 범위, 패턴의 numpy 배열을 생성
** linspace 함수는 일정범위에 일정한 간격으로 요소를 가지는 numpy 배열을 생성
** zeros함수 0 으로 이루어진 numpy 배열생성
** ones함수는
사용시 주의사항
- 리스트와 달리 같은 데이터 타입만 저장가능 (arr이면 arr, float64면 flat64, int면 int)
- 기본 dtype 은 float64임.
[ 배열의 데이터 타입 dtype ]
** Python에서는 허수가 ' j '
** Type code는 Type을 줄여쓴 표기로써, Type code과 Type은 결과가 같다.
** Numpy 와 Python 의 연산자는 크게 차이가 없지만, methods/attributes에서는 NumPy가많다.
(Python - int : 8개 <-> NumPy - int 68개)
< Numpy 와 Python 의 쓰는 법 차이 >
x_py = 123
x_np = np.int64(123)
int (정수형)
i, int_, int32, int64, i8
int_ : 기본 정수 타입, C에서의 long
intc : C에서의 int와 동일
intp : 인덱싱에서 사용하는 정수
dtype (num : bit) |
코드 (num:byte) |
설명 | 예제 |
int8 | i1 | 부호 있는 8비트 정수형 | -128 ~ 127 |
int16 | i2 | 부호 있는 16비트 정수형 | -32768 ~ 32767 |
int32 | i4 | 부호 있는 32비트 정수형 | -2147483648 ~2147483647 |
int64 | i8 | 부호 있는 64비트 정수형 | -9223372036854775808 ~9223372036854775807 |
float (실수형)
f, float_, float 32, float64, f8
dtype (num : bit) |
코드 (num:byte) |
설명 | 예제 |
float16 | f2 | 실수형 ; 반 정밀도 부동소수점형 | 부호 1비트 지수 5비트 가수 10비트 |
float32 | f4 | 실수형; '단 정밀도' 부동소수점형 (Half precision) | 부호 1비트 지수 8비트 가수 23비트 |
float64 | f8 | 실수형; '배 정밀도' 부동소수점형 (Single precision) | 부호 1비트 지수 11비트 가수 54비트 |
float128 | f16 | 실수형; '네배 정밀도' 부동소수점형 (Double precision) | 부호 1비트 지수 15비트 가수 112비트 |
complex (복소수형 자료형)
complex_ , complex64, complex128
dtype (num : bit) |
코드 (num:byte) |
설명 | 예제 |
complex_ | complex128의 약칭 | ||
complex64 | 두개의 32비트 부동 소수점으로 표시되는 복소수, 실수부분과 허수부분에 각각의 float64의 자료형 |
||
complex128 | 두개의 64비트 부동 소수점으로 표시되는 복소수,실수부분과 허수부분에 각각의 float64의 자료형 |
str (문자열)
str, U, U32
str : 문자열 타입
유니코드 : U는 유니코드 문자열을 의미
U32(str) : 데이터 용량을 같이 쓴 경우. 32비트 리틀 엔디안 방식으로 언패킹.
* uint에 대해 좀더 자세히?
파이썬 자료들에서는 U, U32가 문자열 타입의 한종류, 유니코드를 의미하는 것 정도만 알면 된다고 나와있다.
C언어로 구현된 파이썬 라이브러리 Numpy 이다보니, C에서 사용하는 u8,u16,u32,u64의 형태를 확인할 수 있다.
C언어 사용시 char, int, long 등보다는 명확히 몇비트 변수인지 알고 사용 가능.
각 OS(arch) 마다 typedef로 재정의한 변수타입 (int, float은 arch마다 크기 다를 수있음)
uint8,16,32,64의 단위마닫 값차이가 많이 난다.
dtype (num : bit) |
코드 (num:byte) |
설명 | 예제 |
uint8 | Unsinged int형태 unsigned char |
0 to 255 | |
uint16 | Unsinged int형태 unsigned short, unsigned short int |
0 to 65535 | |
uint32 | Unsinged int형태 unsigned, unsigned int |
0 to 4294967295 | |
uint64 | Unsinged int형태 | 0 to 18446744073709551615 |
*np.dtype('str') 로 축약어를 사용하면 다양한 타입을 지정가능.
예)
np.dtype('int32') : 32비트 LE 정수, np.int32와 동일
np.dtype('i4') : 4바이트 LE 정수, np.int32와 동일
np.dtype('f8') : 8바이트 LE 실수, np.float64와 동일
np.dtype('>f8') : 8바이트 BE 실수
* 잠깐 ! 리틀 엔디안('<')은 작은수부터 큰수 default 순서 / 빅 엔디안은 ('>')은 큰수부터 작은수로 역순.
정수형의 경우 i{byte}, int{bit}, <i{byte}, >i{byte} 형태 가능 ( '<'는 LE(리틀 엔디안)의미하며 디폴트 )
실수형의 경우 f{byte}, float{bit}, <f{byte}, >f{byte} 형태 가능
축약어 |
|
bool (부울)
?, bool_
dtype (num : bit) |
코드 (num:byte) |
설명 | 예제 |
bool_ | ? | 바이트 형태로 저장되는 Boolean 타입, 하나의 바이트로 거짓과 참 표현 |
[True, True, False, False] |
Data Type 객체(dtype)
명령어를 통해 각 배열에 데이터 타입을 지정가능
명령어 : numpy.dtype(object, align, copy)
- object : data type객체를 통해 변경될 부분 (기존형태)
- copy : data type객체를 복사하여 새로운 객체 생성
데이터 형태 지정 : np.array([xx, xx], dtype=np.Type
np.array([xx, xx], dtype=np.'Type Code'
np.Type([xx, xx])
데이터 형태 확인 : object.dtype #object의 자료형을 출력
데이터 형태 변경 : object.astype(np.Type) #object에 기존형태, Type에 변경후 형태
np.Type(object) #object에 기존형태, Type에 변경후 형태
[ ndarray 차원 관련 속성 ]
ndim & shape
1차원배열
list = [0, 1, 2, 3]
arr= np.array(list)
print(arr.ndim) # 1
print(arr.shape) # (4,)
2차원배열
list = [[0,1,2],[3,4,5]]
arr= np.array(list)
print(arr.ndim) # 2
print(arr.shape) # (2,3)
ndarray의 크기속성과 shape조절
arr= np.array([0, 1, 2, 3, 4])
print("arr.shape: {}".format(arr.shape)) # arr.shape: (5,)
print("배열요소의수:{}".format(arr.size)) # 배열요소의수:5
print("배열의길이:{}".format(len(arr))) # 배열의길이:1 >> 배열안에 리스트 한줄로 되있어서!
print( "arr.shape: {}".format(arr.shape) ) # arr.shape: (3,2)
print( "배열요소의수:{}".format(arr.size) ) # 배열요소의수:6
print( "배열의길이:{}".format(len(arr)) ) # 배열의길이:3 >> [0,1] [2,3] [4,]
위의 예제를 통해서 알수 있는 것! size , len 의 특성
** size 는 단순 길이 이상, 다차원 배열이 품고있는 요소 개수 전체 리턴
** len 은 다차원 배열이어도 한차원 배열만 체크 가능
reshape
reshape을 이용하면 shape 를 바꿀 수가 있다. 배열의 형태를 바꿈.
이때 '-1'을 넣을 경우, '-1'은 원래 배열의 길이와 남은 차원으로 부터 추정
[ numpy 의 인덱스와 슬라이싱 ]
x = np.arage(7)
인덱싱
-인덱스로 값을 찾아냄
pritn(x[3]) #3
x=np.arage(1,13,1)
x.shape = 3,4
print(x[1:2, 2:3]) # [[5]]
print(x[1: , :2 ]) #[[5 6]
[9 10]]
x[0] =10
print(x) # [10 1 2 3 4 5 6]
슬라이싱
-인덱스의 값으로 배열의 일부 불러옴.
print(x[1:4]) #[0 1 2 3 4 5 6]
print(x[::2]) #[0 2 4 6]
#[시작:끝:간격 ]
Boolean indexing: 배열의 각 요소의 선택 여부를 Boolean mask를 이용하여 지정하는 방식 (mask는 영역선택의미)
예) print( x[x % 2 == 0] ) #[0 2 4 6]
Facy indexing : 배열의 각 요소 선택을 Index 배열을 전달하여 지정하는 방식
print(x[[ 1, 3, 5 ]]) #[1 3 5]
조합해서 쓰는 법!
x = np.arange( 1, 13, 1).reshape(3,4) #1부터 13앞(즉12)까지 1간격으로 나열 -> 그걸 3줄로 4개씩 (행 x 열)
print(x)
# [[ 1 2 3 4]]
[5 6 7 8]
[9 10 11 12]]
2. 데이터 조작 및 분석을 위한 pandas
Pandas의 기본 자료 형태 : Series와 DataFrame
Series 데이터
Series 데이터란 Numpy array가 보강된 형태로
Data와 index를 가지고 있는 데이터 형식
- 시리즈 데이터를 만드는 방법
import pandas as pd
series = pd.Series([1,2,3,4], index = ['a', 'b', 'c', 'd'], name="Title")
print(series, "\n") #이때 "'\n'은 "여러줄 출력 newline 궁금할시 '확장문자 출력'
##결과
a 1
b 2
c 3
d 4
Name: Title, dtype: int64
* 추가적 Tip
- pandas의 Series 객체를 만들기 위해, ‘값’과 ‘인덱스’ 매개변수를 각각 넣어주는 방법 있음.
- 딕셔너리를 매개변수로 넣어주는 방법도 있음.
DataFrame 데이터프레임
시리즈 데이터는 하나의 컬럼 값으로 이루어진 반면
데이터 프레임은 여러 개의 컬럼 값을 가질 수 있다.
여러 개의 시리즈 데이터를 이용하여 데이터 프레임을 만듦
# 먼저 population 과 gdp의 시리즈 데이터 생성을 마친후,
아래와 같이 써주면 2개의 시리즈값이 들어간 데이터 프레임 생성.
country = pd.DataFrame({
'population': population,
'gdp':gdp
#데이터 프레임의 인덱스와 컬럼값 확인 하는 방법
print(country.index)
print(country.columns)
pandas에서 조작 및 분석 하려면..
1. 딕셔너리 생성 data{key:value}
2. 시리즈 만듦 seris([1,2,3,4])
3. 데이터프레임 ( 인덱스 / 시리즈 데이터 로 구성된 표!) 만들기
< 예시를 통해 설명하는 pandas 데이터 조작 및 분석 >
1. 딕셔너리 생성 data{key:value}
population_dict = {
'korea': 5180,
'japan': 12718,
'china': 141500,
'usa': 32676
}
2. Series 만들기
DataFrame 생성 가능
> 국가별 인구 수 데이터를 시리즈로 만들 country라는 변수에 저장
dict = {
'korea' : 5180,
'japan' : 12718,
'china' : 141500,
'usa' : 32676
}
country = pd.Series(dict)
print(country)
##결과
korea 5180
japan 12718
china 141500
usa 32676
dtype: int64
-----------------
data = {
'korea': 169320000,
'japan': 516700000,
'china': 1409250000,
'usa': 2041280000,
}
3. 데이터프레임 만들기
country = pd.DataFrame(data) #표형태로 생성됨
country = country.set_index('country') #컨트리(데이터프레임)는 인덱스를 세팅할때 컨트리(키)를 컬럼(표속성)으로 사용하겠다.
DataFrame (표) 속성을 확인하는 방법
print(country.shape). - 행 x 열
print(country.size) - 전체 갯수 (행,열의 곱한값)
print(country.ndim) - 열 = N(차원)
print(country.values) - 컬럼의 내용값 ( 가로세로 컬럼의 속성 제외)
country.to_csv("./country.csv") -csv 파일로 저장
country.to_excel("country.xlsx") -xlsx 파일로 저장
country = pd. read_csv("./country.csv") -csv 파일 불러오기
country = pd.read_excel("country.xlsx") -xlsx 파일 불러오기
** read_csv( ) / read_table( ) / read_fwf( ) 가 있다.
** read_csv( ) / read_table( ) 은 필드 구분 문자(delimiter)가 콤마( , )인지, 탭( \t ) 인지 차이
**
series = pd.Series([1,2,3,4], index = ['a', 'b', 'c', 'd'], name="Title")
country.index.name = "country" #인덱스에 이름 지정
country.columns.name = "Info" #컬럼에 이름 지정
print(country.index) #인덱스 출력
## 결과
Index(['korea', 'japan', 'china', 'usa'], dtype='object')
데이터 선택 및 변경하기
[ pandas 의 인덱스와 슬라이싱 ]
1. ' .loc '
명시적인 인덱스를 참조하는 인덱싱/ 슬라이싱
인덱싱
-인덱스로 값을 찾아냄
country.loc['china'] #인덱싱
슬라이싱
-인덱스의 값으로 배열의 일부 불러옴.
country.loc['japan':'korea', :'population'] #슬라이싱
2. ' .iloc '
파이썬스타일의 정수 인덱스 인덱싱/슬라이싱
인덱싱
-인덱스로 값을 찾아냄
country.iloc[0] #인덱싱
슬라이싱
-인덱스의 값으로 배열의 일부 불러옴.
country.iloc[1:3, :2] #슬라이싱
[ pandas 의 데이터 선택 _ 컬럼 선택 ]
컬럼명 활용하여 DataFrame에서 데이터 선택
예시)
country
country['gdp'] # 시리즈 선택
country[['gdp']] # 데이터 프레임 선택
#시리즈 데이터
korea 5180
japan 12718
china 141500
usa 32676
dtype: int64
#데이터 프레임
population
korea 5180
japan 12718
china 141500
usa 32676
[ pandas 의 조건이 충족되는 값 추출하기 ]
데이터 프레임에서,
각 컬럼마다 조건을 충족하는 값만 추출할 수 있다.
- Numpy의 마스킹 연산처럼 조건식을 직접 쓰는 방법
- query() 함수를 이용하는 방법
** Masking연산이나 query 함수를 활용하여 조건에맞는 DataFrame행 추출가능
예시)
A, B를 가진 2차원의 데이터프레임을 생성하여 df에 저장된 상태일때.
1. A컬럼 값이 0.5보다 작고 B컬럼 값이 0.3보다 큰 값들을 마스킹 연산을 활용하여 출력
print( df[ ( df['A']<0.5 ) & ( df['B']>0.3 ) ] )
#A의 컬럼 값 df['A']
#B의 컬럼 값 df['B']
#마스킹 연산은 df[ (컬럽값1) & (컬럼값2) ]
2. 위와 같은 조건의 값들을 query 함수를 활용하여 출력
print( df.query("A<0.5 and B>0.3") )
#A의 컬럼 값 A
#B의 컬럼 값 B
#마스킹 연산은 df.query(컬럼값1 and 컬럼값2))
[ pandas 의 새로운 컬럼 추가하기 ]
기존 데이터프레임 값을 활용하여 새로운 컬럼을 생성하는 법
- Series도 numpy array처럼 연산자 활용가능
1. country의 두 컬럼을 이용하여 새로운 컬럼을 만들기
- 1인당 GDP(gdp per capita)를 데이터 프레임에 추가
- 1인당 GDP는 gdp를 population으로 나누어 얻음
import numpy as np
import pandas as pd
# 시리즈 2개 (GDP,인구수)의 데이터프레임을 생성
population = pd.Series({'korea': 5180,'japan': 12718,'china': 141500,'usa': 32676})
gdp = pd.Series({'korea': 169320000,'japan': 516700000,'china': 1409250000,'usa': 2041280000})
print("Country DataFrame")
country = pd.DataFrame({"population" : population,"gdp" : gdp})
print(country)
# 데이터프레임에 gdp per capita 칼럼을 추가
gdp_per_capita = country['gdp']/country['population'] # gdp % population = 1인당 GDP
country['gdp per capita'] = gdp_per_capita
#출력
print( country['gdp per capita'] )
[ pandas 의 데이터 추가, 수정 ]
- 리스트로 추가
- 딕셔너리로 추가
df = pd.DataFrame(columns=['이름','나이','주소']) #데이터프레임 생성
df.loc[0] = ['길동', '26', '서울'] #리스트로 데이터 추가
df.loc[1] = {'이름':'철수', '나이':'25', '주소':'인천'} #딕셔너리로 데이터 추가
df.loc[1, '이름'] = '영희' #명시적 인덱스 활용하여 데이터수정
- NaN값으로 초기화된 새로운 컬럼추가
df['전화번호'] = np.nan
# 새로운 컬럼 추가 후 초기화
df.loc[0, '전화번호']='01012341234'
# 명시적 인덱스 활용하여 데이터수정
- 컬럼삭제 - DataFrame에서 '컬럼 삭제' 후 '원본 변경'
.drop('컬럼이름',열 or 행, 변경여부)
df.drop('전화번호', axis= 1, inplace= True)
# .drop은 컬럼삭제
#axis = 1 : 열방향 / axis = 0 : 행방향
#inplace= True : 원본변경 / inplace=False : 원본변경X
index 값 기준으로 정렬하기
- axis = 0: 행인덱스기준정렬(Default오름차순)
df = df.sort_index(axis= 0)
-axis = 1: 열인덱스기준내림차순정렬
df.sort_index(axis= 1, ascending= False)
column 값 기준으로 정렬하기
- col1 컬럼 기준 정렬 defalut 오름차순
df.sort_values('col1',ascending= True)
-col1컬럼기준내림차순정렬
df.sort_values('col1', ascending= False)
-col2컬럼기준오름차순정렬후col2컬럼기준내림차순정렬
df.sort_values(['col2', 'col1'], ascending= [True, False])
[ 데이터 프레임 분석용 함수 ]
집계함수
집계함수는 많은 데이터 값을 입력받아, 이를 요약하는 하나의 값을 반환하는 기능
count(), max(), min(), sum(), mean()
count
데이터 프레임 분석용 함수 count
메서드 활용하여 데이터개수 확인가능 (Default : NaN값제외)
max, min
메서드활용하여최대, 최소값확인가능
(Default : 열기준,NaN값제외)
sum,mean
메서드활용하여 합계및평균계산
(Default : 열기준,NaN값제외)
axis, skipna
인자활용하여합계및평균계산
(행기준,NaN값포함시)
NaN
NaN값이존재하는column의평균구하여NaN값대체
B_avg= df['math'].mean()print(B_avg)
#25.0# NaN값대체
df['math'] = df['math'].fillna(B_avg)
# 평균
df.mean(axis = 1, skipna= False)
import numpy as np
import pandas as pd
data = {
'korean' : [50, 60, 70],
'math' : [10, np.nan, 40]
}
df = pd.DataFrame(data, index = ['a','b','c'])
print(df, "\n")
# 각 컬럼별 데이터 개수
col_num = df.count(axis = 0)
print(col_num, "\n")
# 각 행별 데이터 개수
row_num = df.count(axis = 1)
print(row_num, "\n")
# 각 컬럼별 최댓값
col_max = df.max()
print(col_max, "\n")
# 각 컬럼별 최솟값
col_min = df.min()
print(col_min, "\n")
# 각 컬럼별 합계
col_sum = df.sum()
print(col_sum, "\n")
# 컬럼의 최솟값으로 NaN값 대체
math_min = df['math'].min()
df['math'] = df['math'].fillna(math_min)
print(df, "\n")
# 각 컬럼별 평균
col_avg = df.mean()
print(col_avg, "\n")
분석용 함수
그룹으로 묶기(1) - groupby()
groupby() 함수를 이용하면 키 값을 기준으로 그룹으로 묶음\
간단한 집계를 넘어서서 조건부로 집계하고 싶은경우
import numpy as np
import pandas as pd
df = pd.DataFrame({
'key': ['A', 'B', 'C', 'A', 'B', 'C'],
'data1': [1, 2, 3, 1, 2, 3],
'data2': [4, 4, 6, 0, 6, 1]
})
print("DataFrame:")
print(df, "\n")
# groupby 함수를 이용해봅시다.
# key를 기준으로 묶어 합계를 구해 출력해보세요.
print(df.groupby('key').sum())
# key와 data1을 기준으로 묶어 합계를 구해 출력해보세요.
print(df.groupby(['key','data1']).sum())
분석용 함수
그룹으로 묶기(2) - aggregate() 함수
키값을 기준으로 그룹으로 묶은 결과의 요약 통계량을 구함.
결과값 또한 데이터프레임으로 반환되어 한 눈에 보기 편리.
groupby를통해서집계를한번에계산하는방법
import numpy as np
import pandas as pd
df = pd.DataFrame({
'key': ['A', 'B', 'C', 'A', 'B', 'C'],
'data1': [0, 1, 2, 3, 4, 5],
'data2': [4, 4, 6, 0, 6, 1]
})
print("DataFrame:")
print(df, "\n")
#agregate 메소드에 함수를 매개변수로 넣어줄 때,
#df.groupby('key').aggregate([min, np.median, max])
#min, max, mean, count 등의 특정 함수들은 문자열 형태로 넘겨주실 수 있습니다.
#df.groupby('key').aggregate(['min', np.median, 'max'])
# aggregate를 이용하여 요약 통계량을 산출해봅시다.
# 데이터 프레임을 'key' 칼럼으로 묶고, data1과 data2 각각의 최솟값, 중앙값, 최댓값을 출력하세요.
print(df.groupby('key').aggregate([min, np.median, max]))
# 데이터 프레임을 'key' 칼럼으로 묶고, data1의 최솟값, data2의 합계를 출력하세요.
print(df.groupby('key').aggregate({'data1':min, 'data2':sum}))
filter
그룹으로묶기(3)
groupby를 통해서 그룹속성을 기준으로 데이터필터링
def filter_by_mean(x):
return x['data2'].mean() > 3
df.groupby('key').mean() #1번
df.groupby('key').filter(filter_by_mean) #2번
apply, lambda
그룹으로묶기(4)
groupby를통해서묶인데이터에함수적용
def filter_by_mean(x):
return x['data2'].mean() > 3
df.groupby('key').mean() #1번
df.groupby('key').filter(filter_by_mean) #2번
get_group
그룹으로묶기(4)
groupby로묶인데이터에서key값으로데이터를가져올수있다
df = pd.read_csv("./univ.csv") #상위5개데이터
df.head() #데이터추출
df.groupby("시도").get_group("충남")
len(df.groupby("시도").get_group("충남")) #94
'ML 인공지능' 카테고리의 다른 글
[Python] 파이썬을 이용한 공공 데이터 분석 및 활용(1) (0) | 2021.11.11 |
---|---|
[Python] 데이터분석을 위한 라이브러리 Matplotlib (0) | 2021.11.11 |
[DL] 자격증 (0) | 2021.08.08 |
[AI] 데이터 분석 기본과정_ 라이브러리 (numpy, pandas, matplotlib) (0) | 2021.08.07 |
[ML] google 제공 ML 용어집 _ 한글버젼 삭제전 (0) | 2021.07.29 |
댓글