-
판다스(Pandas)
-
판다스 특징
-
판다스 용도 : 데이터 분석 패키지
-
판다스 데이터 구조
-
시리즈 클래스
-
시리즈 연산
-
시리즈 인덱싱
-
시리즈 슬라이싱
-
시리즈와 딕셔너리 자료형
-
데이터프레임 클래스
-
데이터프레임 속성
-
df.T
-
데이터프레임 인덱싱(열 추출)
-
데이터프레임 슬라이싱 ( 행 추출 )
-
데이터프레임 고급 인덱싱 : loc 인덱서
-
데이터프레임 고급 인덱싱 : iloc 인덱서
-
데이터프레임 열(시리즈) 갱신, 추가, 삭제
-
판다스로 csv 파일 읽기
-
간편 분석 메소드
-
판다스 통계 기본 메소드
-
판다스 활용 월별 평균 풍속을 계산, 선 그래프로 그리기
-
막대그래프로 변경
판다스(Pandas)
- 데이터 분석을 위해 만들어진 파이썬 패키지(라이브러리)
- 엑셀처럼 행과 열로 이루어진 표 형태의 데이터를 처리
- 대부분의 데이터는 시계열(series)이나 표(table)의 형태
- 판다스 패키지 시리즈(Series) 클래스, 데이터프레임(DataFrame) 클래스 제공
- cf) 넘파이 2차원 배열
- 행렬 matrix 형태의 데이터를 지원
- 데이터의 속성을 표시하는 행이나 열의 레이블이 없음
판다스 특징
- 다양한 형태의 데이터에 적합
- 이종 자료형의 열을 가지는 표 데이터
- 시계열 데이터
- 레이블을 가진 행렬 데이터
- 관측 통계 데이터
- 이종 자료형의 열을 가지는 표 데이터
- 핵심 구조
- 시리즈(Series)
- 1차원 구조를 가지는 하나의 열
- 데이터 프레임(DataFrame)
- 복수의 열을 가지는 2차원 데이터
- 시리즈(Series)
- 판다스에서는 열 우선순위
판다스 용도 : 데이터 분석 패키지
- 데이터 수집
- 리스트, 딕셔너리, 넘파이 배열을 데이터 프레임으로 변환
- CSV 파일이나, 엑셀 파일 등에서 데이터 로드
- 원격 파일(JSON), DB로 부터 데이터 로드
- 데이터 전처리
- 데이터 클린징(정제) → 결측값, 중복값, 이상 데이터 처리
- 데이터 추가, 삭제 → 새로운 열 추가, 특정 열 삭제 등
- 데이터 탐색/분석
- 평균, 개수, 상관관계
- 데이터 정렬과 다양한 데이터 조작 → 정렬, 필터
- 그룹 분석, 원-핫 인코딩
판다스 데이터 구조
- 넘파이 배열을 이용하여 구현
- 처리 속도가 빠름
- 값 변경 가능, 데이터 프레임은 크기도 변경 가능
- 시리즈(Series) 클래스
- 라벨이 붙어 있는 1차원 배열(벡터)
- 데이터 프레임(DataFrame) 클래스
- 행과 열로 구성된 2차원 테이블
- 각 열은 시리즈로 구성
- 행의 이름 → 인덱스(index)
- 열의 이름 → 컬럼(columns)
시리즈 클래스
- 시리즈는 1차원 벡터 데이터에 행방향 인덱스를 붙인 것
- 시리즈 객체 = 값(데이터) + 인덱스(데이터의미, 라벨, 키)
- 시리즈 객체 생성
- s = pd.Series(초기값_리스트, index=라벨_리스트)
- 인덱스 생략 시 index=[0,1, … n-1] 로 자동 생성
- s = pd.Series(초기값_리스트, index=라벨_리스트)
- 시리즈 객체 속성(필드)
- s.values → 값(데이터) 참조 변수 : 넘파이 배열
- s.index → 인덱스 리스트 참조 변수
- 시리즈 열 이름, 인덱스 이름(설정 필요)
- s.name → 시리즈 데이터의 이름(열 이름, 헤더) - 하나의 열에 대해서 이름 부여
- s.index.name → 시리즈 인덱스의 이름(인덱스 헤더)
- 시리즈 인덱스 라벨(문자열, 키) 속성
- s.인덱스_라벨명 → 인덱스 라벨에 대응하는 원소값 반환
- 판다스의 기본 타입은 int64이다, 넘파이는 int32
import pandas as pd
s1 = pd.Series([9904312, 3448737, 2890451, 2466052],
index=["서울", "부산", "인천", "대구"])
s1.name = '인구' # 시리즈 이름
s1.index_name = '도시' # 시리즈 인덱스 이름
print(s1, '\n')
print("대구 인구 = ", s1.대구) # 시리즈 인덱스 라벨(문자열) 속성
s2 = pd.Series(range(10, 14)) # 10~13 정수 값으로 시리즈 객체 생성, 인덱스는 생략
print(s2)
시리즈 연산
- 시리즈 데이터는 넘파이 배열
- 벡터화 연산 : 같은 인덱스 요소들끼리 연산(요소별 연산) 적용
- ex) s1 + s2 → 두 시리즈의 요소별 합 반환
- 브로드캐스팅 연산 : 모든 요소에 동일 연산 적용
- ex) s / 1_000_000 → 시리즈 데이터를 10만으로 나눈 결과 반환
s1 = pd.Series(range(3)) # 시리즈 데이터 = array([0, 1, 2]) s2 = pd.Series(range(3, 6)) # 시리즈 데이터 = array([3, 4, 5]) print(s1 + s2) # 벡터화 연산 = 요소별 연산 print(s1 / 10) # 브로드캐스팅 연산
- 벡터화 연산 : 같은 인덱스 요소들끼리 연산(요소별 연산) 적용
시리즈 인덱싱
- 시리즈 데이터는 넘파이 배열
- 인덱싱 지원
- 정수 인덱싱 → ex) s[3]
- 라벨(label, 문자열) 인덱싱 → ex) s[‘대구’]
- 배열 인덱싱 → ex) s[ [0, 3] ] == s [ [‘서울’,‘대구‘] ]
- 논리 인덱싱 → ex) s[ [True, False, False, True] ]
- 인덱싱 지원
import pandas as pd
s = pd.Series([9904312, 3448737, 2890451, 2466052],
index=["서울", "부산", "인천", "대구"])
print(s[3], s['대구'], '\n') # s[3] == s['대구'] 첨자 인덱싱 = 라벨 인덱싱
print(s[[0,3]], '\n' , s[['서울', '대구']],'\n') # s[[0,3]] == s[['서울', '대구']], 배열 인덱싱
print(s[(250e4 < s) & (s < 500e4)], '\n') # 논리 인덱싱, 인구가 250만 초과, 500만 미만경우
시리즈 슬라이싱
- 시리즈 데이터는 넘파이 배열
- 슬라이싱 지원
- 정수범위 슬라이싱
- ex) s[1:3] → 인덱스 1에서 2까지 요소만 추출(인덱스 3 미포함)
- 라벨(label, 문자열)범위 슬라이싱
- ex) s[‘부산’:‘대구’] → 부산에서 대구까지(대구 포함)
- 슬라이싱 지원
s = pd.Series([9904312, 3448737, 2890451, 2466052],
index=["서울", "부산", "인천", "대구"])
print(s[1:3], '\n') # 두번째(1) 부터 세번째(2) 까지 (네번째(3) 미포함)
print(s["부산" : "대구"], '\n') # 부산에서 대구까지 (대구도 포함)
시리즈와 딕셔너리 자료형
- 딕셔너리 : 키와 값 쌍으로 저장하는 자료구조
- 키를 이용한 인덱싱 가능 → 시리즈도 키(라벨)을 이용한 인덱싱
- 데이터 순서 개념이 없음 → 시리즈 인덱스를 통해 순서 개념이 있음
- 시리즈 객체 = 값(데이터) + 인덱스(라벨, 키)
- 시리즈는 순서 개념이 있는 딕셔너리 자료형
- 딕셔너리 초기값으로 시리즈 객체 생성
- ex) s = pd.Series({딕셔리너_초기값}, index=[라벨_리스트])
딕셔너리는 순서 개념이 없음 반드시 인덱스를 사용해야함
# 딕셔너리
import pandas as pd
s = pd.Series({"서울": 9631482, "부산": 3393191, "인천": 2632035, "대전": 1490158},
index=["부산", "서울", "인천", "대전"])
for k, v in s.items():
print("%s = %d" % (k, v))
데이터프레임 클래스
- 2차원 데이터를 표의 형태로 처리하는 자료구조
- 2차원 행렬 데이터에 인덱스를 붙인 것
- 행(방향) 인덱스 = index = 행 이름(라벨, 번호)
- 열(방향) 인덱스 = columns = 열 이름(라벨, 헤더)
- 데이터프레임 생성
- df = pd.DataFrame**(data, index=행이름, columns=열이름)**
- data
- 딕셔너리 형식 → {0열_이름:0열_데이터, 1열_이름:1열_데이터 ... }
- 2차원 배열 형식 → [ [0열_데이터], [1열_데이터], ... ]
- index = 행이름 리스트(행 라벨 지정, 행 순서 부여)
- 인덱스 생략 시 행번호 리스트 [0, 1..., n-1] 로 자동 설정
- columns = 열이름 리스트(열 라벨 지정, 열의 순서 부여)
# 데이터 프레임
import pandas as pd
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
print(df)
6개 열 키로만 사용할 수 있고 인덱스로 사용 못함
4 행
데이터프레임 속성
- df.values → 데이터(값)을 넘파이 2차원 배열로 반환
- df.columns → 열 인덱스 객체 : 열 이름 리스트를 Index 객체로 반환
- df.index → 행 인덱스 객체 : 행 이름 리스트를 Index 객체로 반환
- 행 인덱스 이름, 열 인덱스 이름 속성(설정 필요)
- df.index.name → 행방향 인덱스 이름(행 인덱스 헤더)
- df.columns.name → 열방향 인덱스 이름(열 인덱스 헤더)
# 데이터 프레임 속성
df = pd.DataFrame(data, index=index, columns=columns)
print(df.values, '\n')
print(df.columns, '\n')
print(df.index, '\n')
df.index.name, df.columns.name = '도시', '특성'
print(df)
포인트 : values는 넘파이 배열 형태로 나와서 콤마가 없음,
index.name을 추가 하니까 행이 추가되었고, columns.name 을 하니 열이 추가됨
df.T
- 데이터프레임 데이터(2차원 배열)의 전치 행렬 반환
- == df.transpose()
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
print(df.T) # == df.transpse()
데이터프레임 인덱싱(열 추출)
- 데이터프레임은 열 라벨(키)과 열 시리즈(값)의 딕셔너리
- 하나의 열이름(열라벨, 키)로 인덱싱
- df[열이름] → 시리즈 객체 반환
- 열이름 리스트로 인덱싱
- df[ [열이름_리스트] ] → 부분적인 데이터프레임 객체 반환
- cf) 열 인덱스가 문자열 라벨인 경우 è 열번호(정수) 인덱싱 사용 불가
- 하나의 열이름(열라벨, 키)로 인덱싱
판다스는 열 우선으로 접근한다
열 하나는 시리즈 반환되고 열이 여러개이면 데이터프레임 형태로 반환된다.
# 데이터 프레임 인덱싱(열 추출)
print(df['지역']) # 시리즈 객체 반환
print('-------------------------')
print(df[['2010', '2015']]) # 부분적인 데이터프레임 객체 반환
데이터프레임 슬라이싱 ( 행 추출 )
- 데이터프레임에 슬라이싱 적용
- 행번호(정수)를 사용한 슬라이싱 : 행번호범위
- df[ s : e] → 행번호 s에서 행번호 e-1 사이의 부분 데이터프레임 반환
- s는 생략 시 0, e는 생략 시 N(전체 행의 수)
- df[ s : e] → 행번호 s에서 행번호 e-1 사이의 부분 데이터프레임 반환
- 행라벨(행이름)를 사용한 슬라이싱 : 행라벨범위
- df[ 시작_행라벨 : 끝_행라벨 ] → 부분적인 데이터프레임 객체 반환
- 시작 행라벨에서 끝 행라벨 사이의 데이터프레임 반환
- 반환 값에 끝 행라벨의 행이 포함됨
- df[ 시작_행라벨 : 끝_행라벨 ] → 부분적인 데이터프레임 객체 반환
- cf) 개별 데이터 인덱싱
- df[열이름][행이름], df[열이름][행번호]
- 데이터프레임은 열(시리즈) 우선
행은 번호로 대체될 수 있지만 컬럼은 고유의 로만 사용 가능
인덱싱은 열 추출 , 슬라이싱은 행 추출
# 데이터 프레임 슬라이싱 1행과 2행의 데이터를 데이터프레임으로 출력
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
print(df[ 1 : 3]) # 데이터 프레임에 3행 데이터 미포함
print('------------------------------------------')
print(df["서울" : "부산"]) # 데이터프레임에 "부산"행 데이터 포함
print('------------------------------------------')
print(df['2015']['서울'], df["2015"][0]) # 이런거 시험문제에 나올 수 도 있음
# 예를 들어 서울 행의 가장 첫번째 열을 출력 하여라/
데이터프레임 고급 인덱싱 : loc 인덱서
- loc 인덱서 → **행 이름(라벨)**을 이용한 인덱싱, 행 우선
- df.loc[행이름] → 해당 행의 데이터를 시리즈 객체로 반환
- df.loc[행범위] → df.loc[행이름1 : 행이름2]
- 행범위에 포함되는 부분 데이터프레임 반환
- == df[행 인덱싱1 : 행인덱싱****2]
기본적으로는 열 우선인데 행 우선으로 바뀐다.
loc의 인수가 하나이면 시리즈 형태로 반환, 슬라이싱 사용 시 데이터프레임으로 반환
사용하는 이유 ? : 행을 전달하고 싶으면 loc 인덱스 사용 , 열 위주는 그냥 인덱스로 접근
슬라이싱은 loc을 통해 접근 할 수 도있고, 사용하지 않아도 똑같은 어차피 행 우선이니까
인덱싱은 loc이 있으면 행우선 없으면 열 우선
import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df); print('---------------------------')
print(df.loc['r2']); print('---------------------------') # r2행의 데이터를 시리즈로 반환
print(df.loc['r2' : 'r3']) # r2 ~ r3 행의 데이터를 데이터프레임으로 반환
- df.loc[행범위, 열범위] → 해당 행범위, 열범위의 부분 데이터프레임 반환
- df.loc[행범위, 열이름] → 열이름 column의 일부분을 시리즈로 반환
- df.loc[행이름, 열범위] → 행이름 row의 일부분을 시리즈로 반환
- df.loc[행이름, 열이름] → 개별데이터 인덱싱 == df[열인덱싱][행인덱싱]
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df.loc[:, :]); print('------------------------------') # 전체 행/ 열 범위 데이터프레임 반환
print(df.loc['r2': 'r3', 'B']); print('------------------------------') # r2 ~ r3 행, B열의 시리즈 반환
print(df.loc['r2':'r3', 'B':'C']); print('------------------------------') # r2~r3 행, B~C열 데이터 프레임 반환
print(df.loc['r2', 'B': 'C']); print('------------------------------') # r2행, B~C열 시리즈 반환
print(df.loc['r2', 'B']); print('------------------------------') # r2행, B열 데이터 반환
- 행범위를 논리(행)배열로 표현 가능 → 참인 부분만 행범위에 포함
- df.loc[논리행배열] → 참인 행 부분 데이터프레임 반환
- df.loc[논리행배열, 열범위] → 참인 행, 열범위 부분 데이터프레임 반환
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df); print('-----------------------') # 전체 데이터프레임 반환
print(df.loc[df.A > 10, 'B']); print('-----------------------') # 참인 행, B열의 시리즈 반환
print(df.loc[df.A > 10, 'B' : 'C']); print('-----------------------') # 참인 행, B~C열의 데이터프레임 반환
데이터프레임 고급 인덱싱 : iloc 인덱서
- iloc 인덱서 → **행 번호(정수 인덱스)**를 이용한 인덱싱, 행 우선
- df.iloc[행번호] → 해당 행의 데이터를 시리즈 객체로 반환
- df.iloc[행범위] → df.iloc[행번호1 : 행번호2]
- df.iloc[행범위, 열범위] → 정수인덱스 행/열 범위 데이터프레임 반환
- df.iloc[행범위, 열번호] → 정수인덱스 행범위, 열번호 시리즈 반환
- == df.loc**[행범위,** 열이름**]**
- df.iloc[행번호, 열범위] → 행번호, 정수인덱스 열범위 시리즈 반환
- == df.loc**[행이름,** 열범위**]**
- df.iloc[행번호, 열번호] → 개별데이터 인덱싱
- == df[열인덱싱][행인덱싱] == df.loc**[행이름,** 열이름**]**
슬라이싱 슬라이싱하면 데이터프레임
슬라이싱 인덱싱이면 시리즈
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df.iloc[:, :]); print('---------------------') # 전체 행/열 범위 데이터프레임 반환
print(df.iloc[1:3, 1]); print('---------------------') # 1~2행, 1열의 시리즈 반환
print(df.iloc[1:3, 1:3]); print('---------------------') # 1~2행, 1~2열 데이터프레임 반환
print(df.iloc[1, 1:3]); print('---------------------') # 1행, 1~2열 시리즈 반환
print(df.iloc[1, 1]); print('---------------------') # 1행, 1열 데이터 반환
데이터프레임 열(시리즈) 갱신, 추가, 삭제
- 데이터프레임은 열 라벨(키)과 열 시리즈(값)의 딕셔너리
- 열(시리즈) 단위로 데이터 갱신, 추가, 삭제 가능
- 열(시리즈) 갱신
- df[열이름] = 값_리스트 → df[열이름]은 시리즈 객체
- 열 시리즈와 같은 크기의 리스트(배열) 필요
- df[열이름] = 값_리스트 → df[열이름]은 시리즈 객체
- 열(시리즈) 추가
- df[새로운_열이름] = 값**_**리스트
- cf**) df =** df.assign**(열이름 = 값_리스트)**
- df[새로운_열이름] = 값**_**리스트
- 열(시리즈) 삭제
- del df[열이름] == df.drop**(열이름,** inplace**=True, axis=1)**
딕셔너리의 기법을 사용한다고 보면 됨 만약 해당 열이 있으면 갱신 하고 없으면 새로운 열을 만들어서 값을 추가한다.
중요한 개념!!!!
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
df["2010`2015 증가율"] = df["2010-2015 증가율"] * 100 # 열 시리즈 값 갱신
df['2005-2010 증가율'] = ((df["2010"] - df["2005"]) / df["2005"] * 100).round(2) # 열 추가
del df['지역'] # 열 삭제
print(df)
판다스로 csv 파일 읽기
- 판다스 csv 파일 읽기 함수
- df = pd.read_csv(파일경로) → 데이터프레임 객체 반환
- df = pd.read_csv(파일경로, index_col=열이름/열번호)
- index_col : 행 인덱스(행번호)로 사용할 열 지정
- 만약 index_col 를 사용하지 않으면 불러올 때 자동으로 인덱스가 0 부터 달
- df = pd.read_csv(파일경로, names=[열이름_리스트])
- names : 열 인덱스 별도 전달
- cf) 데이터프레임 데이터를 csv 파일에 쓰기
- df.to_csv**(파일경로)**
df = pd.read_csv('sample.csv')
# -> 0행을 열 인덱스로 간주한다.
df = pd.read_csv('sample.csv', index_col=0)
# 0열을 행 인덱스(행번호)로 지정한다.
df = pd.read_csv('sample.csv', names=['c1','c2','c3'], index_col='c1')
# 열로 사용할 리스트를 전달하고 'c1'을 행 번호(인덱스)로 지정한다.
- df = pd.read_csv(파일경로)
- 데이터프레임 객체 반환
- index 배열 = [0, 1, 2, ….] 자동으로 추가된다.
df = pd.read_csv('weather.csv', encoding='utf-8') # CSV 파일 열기 => 데이터프레임 반환
print(df)
- df = pd.read_csv(파일경로, index_col=열이름/열번호)
- 데이터프레임 객체 반환
- index_col으로 지정한 열을 index 배열로 사용
df = pd.read_csv('weather.csv', encoding='utf-8', index_col=0)
# 0번째 행 == '일시' 를 인덱스로 지정
간편 분석 메소드
- df.head(n=5) 메소드
- 데이터프레임의 처음 n행만 포함하는 데이터프레임 반환
- df.tail(n=5) 메소드
- 데이터프레임의 마지막 n행만 포함하는 데이터프레임 반환
- df.describe() 메소드
- 데이터프레임의 수치데이터 열(시리즈)에 대해 기본적인 통계 결과 반환
- 반환형 : DataFrame
- 분석 내용 → 판다스에 수치데이터 통계 분석 메소드 모두 제공
- count(개수), mean(평균), std(표준편차)
- min, 25%, 50%, 70%, max
- 데이터프레임의 수치데이터 열(시리즈)에 대해 기본적인 통계 결과 반환
df = pd.read_csv('weather.csv')
print(df.head()); print('-------------------------------') # 데이터프레임의 처음 n행만 포함하는 데이터프레임 반환 디폴트값 5
print(df.tail()); print('-------------------------------') # 데이터프레임의 마지 n행만 포함하는 데이터프레임 반환 디폴트값 5
print(df.describe()) # 데이터프레임의 수치데이터 열(시리즈)에 대해 기본적인 통계 결과 반환
판다스 통계 기본 메소드
- df.count() 메소드
- 데이터프레임 각 열의 데이터 개수 반환 → 반환형 : Series
- cf) df[열이름].count() → 단일 column의 데이터 개수(정수) 반환
- df.mean() 메소드
- 데이터프레임 수치데이터 각 열의 데이터 평균 반환 → 반환형 : Series
- cf) df[열이름].mean() → 수치데이터 column의 평균(실수) 반환
- 조건별 평균
- df.loc[논리행배열, 열이름].mean()
- 참인 행의 열이름 column의 모든 데이터의 평균(실수) 반환
- 논리행배열 → 행의 크기와 동일, True/False를 원소로 가짐
- 참(True) 행에 대해서만 연산 적용하기위해 사용
- df.loc[논리행배열, 열이름].mean()
# 판다스 통계 기본 메소드
import pandas as pd
df = pd.read_csv('weather.csv', encoding='utf-8')
print(df.count()) # 모든 열의 데이터 개수, 시리즈 반환
print('----------------------------------------')
print(df.mean()) # 모든 수치데이터 열의 평균, 데이터프레임 반환
print('----------------------------------------')
print(df['평균기온'].mean()) # 평균기온 열의 평균
print('----------------------------------------')
print(df.loc[df['평균풍속'] >= 4 , '평균기온'].mean()) # 평균풍속이 4이상인 행, 평균기온 열의 평균
# 평균풍속이 4 이상인 행을 모두 가져오고 그 중에 평균기온의 행의 평균을 계산한다.
# 논리계산을 이용하였다.
판다스 활용 월별 평균 풍속을 계산, 선 그래프로 그리기
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
weather = pd.read_csv('weather.csv')
monthly = [0 for x in range(12)] # 달 별로 구분된 12개의 데이터를 담을 리스트
monthly_wind = [0 for x in range(12)] # 각 달의 평균 풍속을 담을 리스트
weather['month'] = pd.DatetimeIndex(weather['일시']).month
for i in range(12) :
monthly[i] = weather[ weather['month'] == i + 1]
monthly_wind[i] = monthly[i].mean()['평균풍속']
plt.plot(monthly_wind, 'red')
plt.show()
# 1월에서 12월달에 그 각 달의 평균값을 그래프로 그려주는 코드임
💡 monthly[i] = weather[weather[’month’] == i + 1
weather[’month’] 는 weather 데이터프레임에 “월”의 정보가 담긴 행을 추가한다
monthly[i]가 뜻하는 바는 monthly[i] 번째에 weather 데이터프레임의 month의 (i+1) 들을 불러와서 monthly[i]에 저장을 한다는 뜻이다.
i+1를 사용하는 이유는 i는 0부터 시작하고 month는 1부터 시작하기때문
막대그래프로 변경
# 추가실습) 막대그래프 변경, x축 값을 1월 ~ 12월 변경
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
weather = pd.read_csv('weather.csv')
weather['month'] = pd.DatetimeIndex(weather['일시']).month
monthly = [ weather[ weather['month'] == i+1] for i in range(12) ]
monthly_wind = [ monthly[i]['평균풍속'].mean() for i in range(12)]
print(monthly_wind)
xlabel = [1,2,3,4,5,6,7,8,9,10,11,12]
plt.figure(figsize=(20,10))
plt.xticks(xlabel)
plt.bar(xlabel,monthly_wind)
plt.show()
판다스(Pandas)
- 데이터 분석을 위해 만들어진 파이썬 패키지(라이브러리)
- 엑셀처럼 행과 열로 이루어진 표 형태의 데이터를 처리
- 대부분의 데이터는 시계열(series)이나 표(table)의 형태
- 판다스 패키지 시리즈(Series) 클래스, 데이터프레임(DataFrame) 클래스 제공
- cf) 넘파이 2차원 배열
- 행렬 matrix 형태의 데이터를 지원
- 데이터의 속성을 표시하는 행이나 열의 레이블이 없음
판다스 특징
- 다양한 형태의 데이터에 적합
- 이종 자료형의 열을 가지는 표 데이터
- 시계열 데이터
- 레이블을 가진 행렬 데이터
- 관측 통계 데이터
- 이종 자료형의 열을 가지는 표 데이터
- 핵심 구조
- 시리즈(Series)
- 1차원 구조를 가지는 하나의 열
- 데이터 프레임(DataFrame)
- 복수의 열을 가지는 2차원 데이터
- 시리즈(Series)
- 판다스에서는 열 우선순위
판다스 용도 : 데이터 분석 패키지
- 데이터 수집
- 리스트, 딕셔너리, 넘파이 배열을 데이터 프레임으로 변환
- CSV 파일이나, 엑셀 파일 등에서 데이터 로드
- 원격 파일(JSON), DB로 부터 데이터 로드
- 데이터 전처리
- 데이터 클린징(정제) → 결측값, 중복값, 이상 데이터 처리
- 데이터 추가, 삭제 → 새로운 열 추가, 특정 열 삭제 등
- 데이터 탐색/분석
- 평균, 개수, 상관관계
- 데이터 정렬과 다양한 데이터 조작 → 정렬, 필터
- 그룹 분석, 원-핫 인코딩
판다스 데이터 구조
- 넘파이 배열을 이용하여 구현
- 처리 속도가 빠름
- 값 변경 가능, 데이터 프레임은 크기도 변경 가능
- 시리즈(Series) 클래스
- 라벨이 붙어 있는 1차원 배열(벡터)
- 데이터 프레임(DataFrame) 클래스
- 행과 열로 구성된 2차원 테이블
- 각 열은 시리즈로 구성
- 행의 이름 → 인덱스(index)
- 열의 이름 → 컬럼(columns)
시리즈 클래스
- 시리즈는 1차원 벡터 데이터에 행방향 인덱스를 붙인 것
- 시리즈 객체 = 값(데이터) + 인덱스(데이터의미, 라벨, 키)
- 시리즈 객체 생성
- s = pd.Series(초기값_리스트, index=라벨_리스트)
- 인덱스 생략 시 index=[0,1, … n-1] 로 자동 생성
- s = pd.Series(초기값_리스트, index=라벨_리스트)
- 시리즈 객체 속성(필드)
- s.values → 값(데이터) 참조 변수 : 넘파이 배열
- s.index → 인덱스 리스트 참조 변수
- 시리즈 열 이름, 인덱스 이름(설정 필요)
- s.name → 시리즈 데이터의 이름(열 이름, 헤더) - 하나의 열에 대해서 이름 부여
- s.index.name → 시리즈 인덱스의 이름(인덱스 헤더)
- 시리즈 인덱스 라벨(문자열, 키) 속성
- s.인덱스_라벨명 → 인덱스 라벨에 대응하는 원소값 반환
- 판다스의 기본 타입은 int64이다, 넘파이는 int32
import pandas as pd
s1 = pd.Series([9904312, 3448737, 2890451, 2466052],
index=["서울", "부산", "인천", "대구"])
s1.name = '인구' # 시리즈 이름
s1.index_name = '도시' # 시리즈 인덱스 이름
print(s1, '\n')
print("대구 인구 = ", s1.대구) # 시리즈 인덱스 라벨(문자열) 속성
s2 = pd.Series(range(10, 14)) # 10~13 정수 값으로 시리즈 객체 생성, 인덱스는 생략
print(s2)
시리즈 연산
- 시리즈 데이터는 넘파이 배열
- 벡터화 연산 : 같은 인덱스 요소들끼리 연산(요소별 연산) 적용
- ex) s1 + s2 → 두 시리즈의 요소별 합 반환
- 브로드캐스팅 연산 : 모든 요소에 동일 연산 적용
- ex) s / 1_000_000 → 시리즈 데이터를 10만으로 나눈 결과 반환
s1 = pd.Series(range(3)) # 시리즈 데이터 = array([0, 1, 2]) s2 = pd.Series(range(3, 6)) # 시리즈 데이터 = array([3, 4, 5]) print(s1 + s2) # 벡터화 연산 = 요소별 연산 print(s1 / 10) # 브로드캐스팅 연산
- 벡터화 연산 : 같은 인덱스 요소들끼리 연산(요소별 연산) 적용
시리즈 인덱싱
- 시리즈 데이터는 넘파이 배열
- 인덱싱 지원
- 정수 인덱싱 → ex) s[3]
- 라벨(label, 문자열) 인덱싱 → ex) s[‘대구’]
- 배열 인덱싱 → ex) s[ [0, 3] ] == s [ [‘서울’,‘대구‘] ]
- 논리 인덱싱 → ex) s[ [True, False, False, True] ]
- 인덱싱 지원
import pandas as pd
s = pd.Series([9904312, 3448737, 2890451, 2466052],
index=["서울", "부산", "인천", "대구"])
print(s[3], s['대구'], '\n') # s[3] == s['대구'] 첨자 인덱싱 = 라벨 인덱싱
print(s[[0,3]], '\n' , s[['서울', '대구']],'\n') # s[[0,3]] == s[['서울', '대구']], 배열 인덱싱
print(s[(250e4 < s) & (s < 500e4)], '\n') # 논리 인덱싱, 인구가 250만 초과, 500만 미만경우
시리즈 슬라이싱
- 시리즈 데이터는 넘파이 배열
- 슬라이싱 지원
- 정수범위 슬라이싱
- ex) s[1:3] → 인덱스 1에서 2까지 요소만 추출(인덱스 3 미포함)
- 라벨(label, 문자열)범위 슬라이싱
- ex) s[‘부산’:‘대구’] → 부산에서 대구까지(대구 포함)
- 슬라이싱 지원
s = pd.Series([9904312, 3448737, 2890451, 2466052],
index=["서울", "부산", "인천", "대구"])
print(s[1:3], '\n') # 두번째(1) 부터 세번째(2) 까지 (네번째(3) 미포함)
print(s["부산" : "대구"], '\n') # 부산에서 대구까지 (대구도 포함)
시리즈와 딕셔너리 자료형
- 딕셔너리 : 키와 값 쌍으로 저장하는 자료구조
- 키를 이용한 인덱싱 가능 → 시리즈도 키(라벨)을 이용한 인덱싱
- 데이터 순서 개념이 없음 → 시리즈 인덱스를 통해 순서 개념이 있음
- 시리즈 객체 = 값(데이터) + 인덱스(라벨, 키)
- 시리즈는 순서 개념이 있는 딕셔너리 자료형
- 딕셔너리 초기값으로 시리즈 객체 생성
- ex) s = pd.Series({딕셔리너_초기값}, index=[라벨_리스트])
딕셔너리는 순서 개념이 없음 반드시 인덱스를 사용해야함
# 딕셔너리
import pandas as pd
s = pd.Series({"서울": 9631482, "부산": 3393191, "인천": 2632035, "대전": 1490158},
index=["부산", "서울", "인천", "대전"])
for k, v in s.items():
print("%s = %d" % (k, v))
데이터프레임 클래스
- 2차원 데이터를 표의 형태로 처리하는 자료구조
- 2차원 행렬 데이터에 인덱스를 붙인 것
- 행(방향) 인덱스 = index = 행 이름(라벨, 번호)
- 열(방향) 인덱스 = columns = 열 이름(라벨, 헤더)
- 데이터프레임 생성
- df = pd.DataFrame**(data, index=행이름, columns=열이름)**
- data
- 딕셔너리 형식 → {0열_이름:0열_데이터, 1열_이름:1열_데이터 ... }
- 2차원 배열 형식 → [ [0열_데이터], [1열_데이터], ... ]
- index = 행이름 리스트(행 라벨 지정, 행 순서 부여)
- 인덱스 생략 시 행번호 리스트 [0, 1..., n-1] 로 자동 설정
- columns = 열이름 리스트(열 라벨 지정, 열의 순서 부여)
# 데이터 프레임
import pandas as pd
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
print(df)
6개 열 키로만 사용할 수 있고 인덱스로 사용 못함
4 행
데이터프레임 속성
- df.values → 데이터(값)을 넘파이 2차원 배열로 반환
- df.columns → 열 인덱스 객체 : 열 이름 리스트를 Index 객체로 반환
- df.index → 행 인덱스 객체 : 행 이름 리스트를 Index 객체로 반환
- 행 인덱스 이름, 열 인덱스 이름 속성(설정 필요)
- df.index.name → 행방향 인덱스 이름(행 인덱스 헤더)
- df.columns.name → 열방향 인덱스 이름(열 인덱스 헤더)
# 데이터 프레임 속성
df = pd.DataFrame(data, index=index, columns=columns)
print(df.values, '\n')
print(df.columns, '\n')
print(df.index, '\n')
df.index.name, df.columns.name = '도시', '특성'
print(df)
포인트 : values는 넘파이 배열 형태로 나와서 콤마가 없음,
index.name을 추가 하니까 행이 추가되었고, columns.name 을 하니 열이 추가됨
df.T
- 데이터프레임 데이터(2차원 배열)의 전치 행렬 반환
- == df.transpose()
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
print(df.T) # == df.transpse()
데이터프레임 인덱싱(열 추출)
- 데이터프레임은 열 라벨(키)과 열 시리즈(값)의 딕셔너리
- 하나의 열이름(열라벨, 키)로 인덱싱
- df[열이름] → 시리즈 객체 반환
- 열이름 리스트로 인덱싱
- df[ [열이름_리스트] ] → 부분적인 데이터프레임 객체 반환
- cf) 열 인덱스가 문자열 라벨인 경우 è 열번호(정수) 인덱싱 사용 불가
- 하나의 열이름(열라벨, 키)로 인덱싱
판다스는 열 우선으로 접근한다
열 하나는 시리즈 반환되고 열이 여러개이면 데이터프레임 형태로 반환된다.
# 데이터 프레임 인덱싱(열 추출)
print(df['지역']) # 시리즈 객체 반환
print('-------------------------')
print(df[['2010', '2015']]) # 부분적인 데이터프레임 객체 반환
데이터프레임 슬라이싱 ( 행 추출 )
- 데이터프레임에 슬라이싱 적용
- 행번호(정수)를 사용한 슬라이싱 : 행번호범위
- df[ s : e] → 행번호 s에서 행번호 e-1 사이의 부분 데이터프레임 반환
- s는 생략 시 0, e는 생략 시 N(전체 행의 수)
- df[ s : e] → 행번호 s에서 행번호 e-1 사이의 부분 데이터프레임 반환
- 행라벨(행이름)를 사용한 슬라이싱 : 행라벨범위
- df[ 시작_행라벨 : 끝_행라벨 ] → 부분적인 데이터프레임 객체 반환
- 시작 행라벨에서 끝 행라벨 사이의 데이터프레임 반환
- 반환 값에 끝 행라벨의 행이 포함됨
- df[ 시작_행라벨 : 끝_행라벨 ] → 부분적인 데이터프레임 객체 반환
- cf) 개별 데이터 인덱싱
- df[열이름][행이름], df[열이름][행번호]
- 데이터프레임은 열(시리즈) 우선
행은 번호로 대체될 수 있지만 컬럼은 고유의 로만 사용 가능
인덱싱은 열 추출 , 슬라이싱은 행 추출
# 데이터 프레임 슬라이싱 1행과 2행의 데이터를 데이터프레임으로 출력
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
print(df[ 1 : 3]) # 데이터 프레임에 3행 데이터 미포함
print('------------------------------------------')
print(df["서울" : "부산"]) # 데이터프레임에 "부산"행 데이터 포함
print('------------------------------------------')
print(df['2015']['서울'], df["2015"][0]) # 이런거 시험문제에 나올 수 도 있음
# 예를 들어 서울 행의 가장 첫번째 열을 출력 하여라/
데이터프레임 고급 인덱싱 : loc 인덱서
- loc 인덱서 → **행 이름(라벨)**을 이용한 인덱싱, 행 우선
- df.loc[행이름] → 해당 행의 데이터를 시리즈 객체로 반환
- df.loc[행범위] → df.loc[행이름1 : 행이름2]
- 행범위에 포함되는 부분 데이터프레임 반환
- == df[행 인덱싱1 : 행인덱싱****2]
기본적으로는 열 우선인데 행 우선으로 바뀐다.
loc의 인수가 하나이면 시리즈 형태로 반환, 슬라이싱 사용 시 데이터프레임으로 반환
사용하는 이유 ? : 행을 전달하고 싶으면 loc 인덱스 사용 , 열 위주는 그냥 인덱스로 접근
슬라이싱은 loc을 통해 접근 할 수 도있고, 사용하지 않아도 똑같은 어차피 행 우선이니까
인덱싱은 loc이 있으면 행우선 없으면 열 우선
import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df); print('---------------------------')
print(df.loc['r2']); print('---------------------------') # r2행의 데이터를 시리즈로 반환
print(df.loc['r2' : 'r3']) # r2 ~ r3 행의 데이터를 데이터프레임으로 반환
- df.loc[행범위, 열범위] → 해당 행범위, 열범위의 부분 데이터프레임 반환
- df.loc[행범위, 열이름] → 열이름 column의 일부분을 시리즈로 반환
- df.loc[행이름, 열범위] → 행이름 row의 일부분을 시리즈로 반환
- df.loc[행이름, 열이름] → 개별데이터 인덱싱 == df[열인덱싱][행인덱싱]
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df.loc[:, :]); print('------------------------------') # 전체 행/ 열 범위 데이터프레임 반환
print(df.loc['r2': 'r3', 'B']); print('------------------------------') # r2 ~ r3 행, B열의 시리즈 반환
print(df.loc['r2':'r3', 'B':'C']); print('------------------------------') # r2~r3 행, B~C열 데이터 프레임 반환
print(df.loc['r2', 'B': 'C']); print('------------------------------') # r2행, B~C열 시리즈 반환
print(df.loc['r2', 'B']); print('------------------------------') # r2행, B열 데이터 반환
- 행범위를 논리(행)배열로 표현 가능 → 참인 부분만 행범위에 포함
- df.loc[논리행배열] → 참인 행 부분 데이터프레임 반환
- df.loc[논리행배열, 열범위] → 참인 행, 열범위 부분 데이터프레임 반환
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df); print('-----------------------') # 전체 데이터프레임 반환
print(df.loc[df.A > 10, 'B']); print('-----------------------') # 참인 행, B열의 시리즈 반환
print(df.loc[df.A > 10, 'B' : 'C']); print('-----------------------') # 참인 행, B~C열의 데이터프레임 반환
데이터프레임 고급 인덱싱 : iloc 인덱서
- iloc 인덱서 → **행 번호(정수 인덱스)**를 이용한 인덱싱, 행 우선
- df.iloc[행번호] → 해당 행의 데이터를 시리즈 객체로 반환
- df.iloc[행범위] → df.iloc[행번호1 : 행번호2]
- df.iloc[행범위, 열범위] → 정수인덱스 행/열 범위 데이터프레임 반환
- df.iloc[행범위, 열번호] → 정수인덱스 행범위, 열번호 시리즈 반환
- == df.loc**[행범위,** 열이름**]**
- df.iloc[행번호, 열범위] → 행번호, 정수인덱스 열범위 시리즈 반환
- == df.loc**[행이름,** 열범위**]**
- df.iloc[행번호, 열번호] → 개별데이터 인덱싱
- == df[열인덱싱][행인덱싱] == df.loc**[행이름,** 열이름**]**
슬라이싱 슬라이싱하면 데이터프레임
슬라이싱 인덱싱이면 시리즈
df = pd.DataFrame(np.arange(10, 22).reshape(3, 4),
index=["r1", "r2", "r3"],
columns=["A", "B", "C", "D"])
print(df.iloc[:, :]); print('---------------------') # 전체 행/열 범위 데이터프레임 반환
print(df.iloc[1:3, 1]); print('---------------------') # 1~2행, 1열의 시리즈 반환
print(df.iloc[1:3, 1:3]); print('---------------------') # 1~2행, 1~2열 데이터프레임 반환
print(df.iloc[1, 1:3]); print('---------------------') # 1행, 1~2열 시리즈 반환
print(df.iloc[1, 1]); print('---------------------') # 1행, 1열 데이터 반환
데이터프레임 열(시리즈) 갱신, 추가, 삭제
- 데이터프레임은 열 라벨(키)과 열 시리즈(값)의 딕셔너리
- 열(시리즈) 단위로 데이터 갱신, 추가, 삭제 가능
- 열(시리즈) 갱신
- df[열이름] = 값_리스트 → df[열이름]은 시리즈 객체
- 열 시리즈와 같은 크기의 리스트(배열) 필요
- df[열이름] = 값_리스트 → df[열이름]은 시리즈 객체
- 열(시리즈) 추가
- df[새로운_열이름] = 값**_**리스트
- cf**) df =** df.assign**(열이름 = 값_리스트)**
- df[새로운_열이름] = 값**_**리스트
- 열(시리즈) 삭제
- del df[열이름] == df.drop**(열이름,** inplace**=True, axis=1)**
딕셔너리의 기법을 사용한다고 보면 됨 만약 해당 열이 있으면 갱신 하고 없으면 새로운 열을 만들어서 값을 추가한다.
중요한 개념!!!!
data = {
"2015" : [9904312, 3448737, 2890451, 2466052],
"2010" : [9631482, 3393191, 2632035, 2431774],
"2005" : [9762546, 3512547, 2517680, 2456016],
"2000" : [9853972, 3655437, 2466338, 2473990],
"지역" : ["수도권", "경상권", "수도권", "경상권"],
"2010-2015 증가율" : [0.0283, 0.0163, 0.0982, 0.0141]
}
index = ["서울", "부산", "인천", "대구"]
columns = ["지역", "2015", "2010", "2005", "2000", "2010-2015 증가율"]
df = pd.DataFrame(data, index=index, columns=columns)
df["2010`2015 증가율"] = df["2010-2015 증가율"] * 100 # 열 시리즈 값 갱신
df['2005-2010 증가율'] = ((df["2010"] - df["2005"]) / df["2005"] * 100).round(2) # 열 추가
del df['지역'] # 열 삭제
print(df)
판다스로 csv 파일 읽기
- 판다스 csv 파일 읽기 함수
- df = pd.read_csv(파일경로) → 데이터프레임 객체 반환
- df = pd.read_csv(파일경로, index_col=열이름/열번호)
- index_col : 행 인덱스(행번호)로 사용할 열 지정
- 만약 index_col 를 사용하지 않으면 불러올 때 자동으로 인덱스가 0 부터 달
- df = pd.read_csv(파일경로, names=[열이름_리스트])
- names : 열 인덱스 별도 전달
- cf) 데이터프레임 데이터를 csv 파일에 쓰기
- df.to_csv**(파일경로)**
df = pd.read_csv('sample.csv')
# -> 0행을 열 인덱스로 간주한다.
df = pd.read_csv('sample.csv', index_col=0)
# 0열을 행 인덱스(행번호)로 지정한다.
df = pd.read_csv('sample.csv', names=['c1','c2','c3'], index_col='c1')
# 열로 사용할 리스트를 전달하고 'c1'을 행 번호(인덱스)로 지정한다.
- df = pd.read_csv(파일경로)
- 데이터프레임 객체 반환
- index 배열 = [0, 1, 2, ….] 자동으로 추가된다.
df = pd.read_csv('weather.csv', encoding='utf-8') # CSV 파일 열기 => 데이터프레임 반환
print(df)
- df = pd.read_csv(파일경로, index_col=열이름/열번호)
- 데이터프레임 객체 반환
- index_col으로 지정한 열을 index 배열로 사용
df = pd.read_csv('weather.csv', encoding='utf-8', index_col=0)
# 0번째 행 == '일시' 를 인덱스로 지정
간편 분석 메소드
- df.head(n=5) 메소드
- 데이터프레임의 처음 n행만 포함하는 데이터프레임 반환
- df.tail(n=5) 메소드
- 데이터프레임의 마지막 n행만 포함하는 데이터프레임 반환
- df.describe() 메소드
- 데이터프레임의 수치데이터 열(시리즈)에 대해 기본적인 통계 결과 반환
- 반환형 : DataFrame
- 분석 내용 → 판다스에 수치데이터 통계 분석 메소드 모두 제공
- count(개수), mean(평균), std(표준편차)
- min, 25%, 50%, 70%, max
- 데이터프레임의 수치데이터 열(시리즈)에 대해 기본적인 통계 결과 반환
df = pd.read_csv('weather.csv')
print(df.head()); print('-------------------------------') # 데이터프레임의 처음 n행만 포함하는 데이터프레임 반환 디폴트값 5
print(df.tail()); print('-------------------------------') # 데이터프레임의 마지 n행만 포함하는 데이터프레임 반환 디폴트값 5
print(df.describe()) # 데이터프레임의 수치데이터 열(시리즈)에 대해 기본적인 통계 결과 반환
판다스 통계 기본 메소드
- df.count() 메소드
- 데이터프레임 각 열의 데이터 개수 반환 → 반환형 : Series
- cf) df[열이름].count() → 단일 column의 데이터 개수(정수) 반환
- df.mean() 메소드
- 데이터프레임 수치데이터 각 열의 데이터 평균 반환 → 반환형 : Series
- cf) df[열이름].mean() → 수치데이터 column의 평균(실수) 반환
- 조건별 평균
- df.loc[논리행배열, 열이름].mean()
- 참인 행의 열이름 column의 모든 데이터의 평균(실수) 반환
- 논리행배열 → 행의 크기와 동일, True/False를 원소로 가짐
- 참(True) 행에 대해서만 연산 적용하기위해 사용
- df.loc[논리행배열, 열이름].mean()
# 판다스 통계 기본 메소드
import pandas as pd
df = pd.read_csv('weather.csv', encoding='utf-8')
print(df.count()) # 모든 열의 데이터 개수, 시리즈 반환
print('----------------------------------------')
print(df.mean()) # 모든 수치데이터 열의 평균, 데이터프레임 반환
print('----------------------------------------')
print(df['평균기온'].mean()) # 평균기온 열의 평균
print('----------------------------------------')
print(df.loc[df['평균풍속'] >= 4 , '평균기온'].mean()) # 평균풍속이 4이상인 행, 평균기온 열의 평균
# 평균풍속이 4 이상인 행을 모두 가져오고 그 중에 평균기온의 행의 평균을 계산한다.
# 논리계산을 이용하였다.
판다스 활용 월별 평균 풍속을 계산, 선 그래프로 그리기
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
weather = pd.read_csv('weather.csv')
monthly = [0 for x in range(12)] # 달 별로 구분된 12개의 데이터를 담을 리스트
monthly_wind = [0 for x in range(12)] # 각 달의 평균 풍속을 담을 리스트
weather['month'] = pd.DatetimeIndex(weather['일시']).month
for i in range(12) :
monthly[i] = weather[ weather['month'] == i + 1]
monthly_wind[i] = monthly[i].mean()['평균풍속']
plt.plot(monthly_wind, 'red')
plt.show()
# 1월에서 12월달에 그 각 달의 평균값을 그래프로 그려주는 코드임
💡 monthly[i] = weather[weather[’month’] == i + 1
weather[’month’] 는 weather 데이터프레임에 “월”의 정보가 담긴 행을 추가한다
monthly[i]가 뜻하는 바는 monthly[i] 번째에 weather 데이터프레임의 month의 (i+1) 들을 불러와서 monthly[i]에 저장을 한다는 뜻이다.
i+1를 사용하는 이유는 i는 0부터 시작하고 month는 1부터 시작하기때문
막대그래프로 변경
# 추가실습) 막대그래프 변경, x축 값을 1월 ~ 12월 변경
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
weather = pd.read_csv('weather.csv')
weather['month'] = pd.DatetimeIndex(weather['일시']).month
monthly = [ weather[ weather['month'] == i+1] for i in range(12) ]
monthly_wind = [ monthly[i]['평균풍속'].mean() for i in range(12)]
print(monthly_wind)
xlabel = [1,2,3,4,5,6,7,8,9,10,11,12]
plt.figure(figsize=(20,10))
plt.xticks(xlabel)
plt.bar(xlabel,monthly_wind)
plt.show()