📊 Pandas 정의


📌 Pandas란?

  • pandas
    - 데이터 분석 및 시각화 관련 기능을 제공하는 라이브러리
    - Numpy 기반 라이브러리
    - 고수준의 자료구조(Series, DataFrame)와 빠르고 쉬운 데이터 분석용 자료구조 및 함수를 제공
    - RDBMS의 데이터를 쉽게 조작하는 기능 존재
    - 인덱싱, 슬라이싱 기능을 통한 편리한 데이터 처리









📊 Pandas Series


📌 Series 객체

  • Series
    - 일련의 객체를 담을 수 있는 1차원 배열과 같은 구조로 index값을 갖는다.

  • Series 생성
    - 리스트 or 튜플 or 딕셔너리로 넣을 수 있다.
    pd.Series([1, 2, 3])
    pd.Series((1, 2, 3))
    pd.Series({'a1':1, 'a2':2, 'a3':3})
obj = Series([3, 7, -5, 4])
# obj = Series((3, 7, -5, 4))
# obj = Series({'a1':3, 'a2':7, 'a3':-5, 'a4':4}
print(obj, type(obj))
# 0    3
# 1    7
# 2   -5
# 3    4
# dtype: int64 <class 'pandas.core.series.Series'>

  • Series 생성 [index 값 지정]
    - pd.Series(리스트, index=['행1', '행2', ....])
obj2 = Series([3, 7, -5, 4], index=['a','b','c','d'])
print(obj2)
# a    3
# b    7
# c   -5
# d    4
# dtype: int64

  • Series 인덱스 이름 변경
    - Series객체.index = ['인덱스명1', '인덱스명2', ....]
obj2.index = ['a1', 'a2', 'a3', 'a4']
print(obj3)
# a1    3
# a2    7
# a3   -5
# a4    4
# dtype: int64

  • Series 이름(칼럼명) 변경
    - Series객체.name = 이름1
obj2.name = '상품가격'
print(obj2)
# a    3
# b    7
# c   -5
# d    4
# Name: 상품가격, dtype: int64

  • Series 내부 요소만 추출
    - 시리즈객체.values
print(obj2.values)
# [ 3  7 -5  4]

  • Series 인덱스(행 이름)만 추출
    - 시리즈객체.index
print(obj2.index)
# Index(['a', 'b', 'c', 'd'], dtype='object')

  • Series 인덱싱
    - 시리즈객체[index] : 인덱싱
    - 시리즈객체[행이름] : 인덱싱
    - 시리즈객체[[index or 행이름]] : Series 형식의 행 전체 추출
print(obj2[0])		# 특정 행의 값 출력
# 3

print(obj2['a'])	# 특정 행의 값 출력
# 3

print(obj2[['a']])	# 특정 행 전체 출력
# a		3
# dtype: int64

print(obj2[['a', 'b']])
# a    3
# b    7
# dtype: int64

  • Series 슬라이싱
    - 시리즈객체[index1:index2] : 행 슬라이싱
print(obj2['a':'b'])
# a    3
# b    7
# dtype: int64

print(obj2[1:4])
# b    7
# c   -5
# d    4
# dtype: int64









📊 Pandas DataFrame 정의


📌 python DataFrame 이란?

  • DataFrame
    - 표 모양(2차원 형태 자료)의 자료구조로 여러 개의 칼럼을 갖는다.
    - Series(칼럼기준 행데이터)들이 모인 형태
    - 각 칼럼은 서로 다른 데이터타입을 갖는다.
    - 하나의 행은 dict 형으로 넣는다.
    - 다수의 행은 dict in list 형태로 지정하여 넣는다.









📊 Pandas DataFrame 기본


📌 python DataFrame 생성

  • DataFrame 생성
    - 하나의 행으로 생성 : pd.DataFrame(dict타입데이터)
    - 다수의 행으로 생성 : pd.DataFrame(dictInList타입데이터)
    - Series로 하나의 칼럼만 만들어 생성 : pd.dataFrame(Series객체)
df = DataFrame(obj2)
#     상품가격
# a1    3
# a2    7
# a3   -5
# a4    4


📌 python DataFrame 행, 열 이름 부여

  • DataFrame 칼럼명 부여
    - pd.DataFrame(데이터, columns=['칼럼명1', '칼럼명2', ....])
    - 데이터프레임객체.columns = ['칼럼명1', '칼럼명2', ....]
# 방법1
df = pd.DataFrame(data, columns=['a1', 'a2'])

# 방법2
df.columns = ['애플워치 성능', '맥북 성능']

  • DataFrame 인덱스명 부여
    - pd.DataFrame(데이터, index=['인덱스명1', '인덱스명2', ....])
    - 데이터프레임객체.index = ['인덱스명1', '인덱스명2', ....]
# 방법1
df = pd.DataFrame(data, index=['인덱스1', '인덱스2'])

# 방법2
df.index = ['index1', 'index2']


📌 python DataFrame 행, 열 추출

  • DataFrame 칼럼 배열 추출
    - 데이터프레임.columns
print(frame.columns)	# 1차원 배열로 반환
[irum juso nai]

  • DataFrame 로우 배열 추출
    - 데이터프레임.values
print(frame.values)		# 2차원 배열로 반환
# [['홍길동' '역삼동' 23]
#  ['한국인' '신당동' 25]
#  ['신기해' '역삼동' 33]
#  ['공기밥' '역삼동' 30]
#  ['한가해' '신사동' 35]]

  • DataFrame 칼럼 순서 변경
    - 칼럼 순서는 ['칼럼명1', '칼럼명2', '칼럼명3'] 이라고 가정한다.
    - pd.DataFrame(data, columns=['칼럼명1', '칼럼명3', '칼럼명2'])
print(DataFrame(data, columns=['juso', 'irum', 'nai']))
#    juso   irum   nai
# 0  역삼동  홍길동   23
# 1  신당동  한국인   25
# 2  역삼동  신기해   33
# 3  역삼동  공기밥   30
# 4  신사동  한가해   35


📌 python DataFrame 행, 열 데이터 핸들링

  • DataFrame 열 데이터 추가
    - 데이터프레임['새로운 열 이름'] = pd.Series(데이터)
df['newCol'] = pd.Series([1, 2, 3])

  • DataFrame 행 데이터 추가
    - 데이터프레임.iloc[len(데이터프레임)] = dict데이터
df.iloc[len(df)] = {'칼럼1':1, '칼럼2':2}

  • DataFrame 행 데이터 삭제
    - 데이터프레임.drop(행이름, axis=0) : 해당 행을 삭제
print(frame.drop('d', axis=0))
#    irum   juso   nai    tel
# a  홍길동  역삼동   23       NaN
# b  한국인  신당동   25  123-2222
# c  신기해  역삼동   33  123-3333
# e  한가해  신사동   35       NaN

  • DataFrame 칼럼 데이터 삭제
    - 데이터프레임.drop(칼럼이름, axis=1) : 해당 칼럼을 삭제
print(frame.drop('tel', axis=1))
#    irum   juso   nai
# a  홍길동  역삼동   23
# b  한국인  신당동   25
# c  신기해  역삼동   33
# d  공기밥  역삼동   30
# e  한가해  신사동   35


📌 python DataFrame 인덱싱

  • DataFrame 칼럼 인덱싱
    - 차원축소된 Series : 데이터프레임['칼럼명1']
    - 차원유지된 DataFrame : 데이터프레임[['칼럼명1']]
print(df['irum'])
# 0  홍길동
# 1  한국인
# 2  신기해
# 3  공기밥
# 4  한가해
# Name: irum, dtype: object <class 'pandas.core.series.Series'>

print(df[['irum']])
print(df.iloc[:, 1])
print(df.loc[:, ['irum']])
#	  irum
# 0  홍길동
# 1  한국인
# 2  신기해
# 3  공기밥
# 4  한가해

print(df.iloc[:, 1])
#	  irum
# 0  홍길동
# 1  한국인
# 2  신기해
# 3  공기밥
# 4  한가해

  • DataFrame 로우 인덱싱
    - 데이터프레임.loc[] : 문자 기반 인덱싱
    - 데이터프레임.iloc[] : 정수 기반 인덱싱
print(df.loc[0, :])
print(df.iloc[0, :])
#	  irum
# 0  홍길동


📌 python DataFrame 슬라이싱

  • DataFrame 칼럼 슬라이싱
    - 데이터프레임.iloc[:, 0:2]
    - 데이터프레임.iloc[:, ['칼럼명1','칼럼명2']]
print(df.iloc[:, 0:2])
print(df.loc[:, ['강남', '강북']])
#     강남  강북
# 1월   0   1
# 2월   3   4
# 3월   6   7
# 4월   9  10

  • DataFrame 로우 슬라이싱
    - 데이터프레임[인덱스1:인덱스2]
    - 데이터프레임.iloc[0:2, :]
    - 데이터프레임.loc[['인덱스명1', '인덱스명2'], :]
print(df[0:2])
print(df.iloc[0:2, :])
print(df.loc[['1월', '2월'], :])
#     강남  강북  서초
# 1월   0   1   2
# 2월   3   4   5


📌 python DataFrame 정렬

  • DataFrame sort_index로 정렬
    - 데이터프레임.sort_index(axis=0, ascending=True or False) : 행 정렬
    - 데이터프레임.sort_index(axis=1, ascending=True or False) : 열 정렬
    - ascending 속성 : 내림차순 or 오름차순 지정
print(frame2.sort_index(axis=0, ascending=False))   # axis=0 행을 기준으로 처리, ascending=False DESC로 정렬
#    irum   juso   nai   tel
# e  한가해  신사동   35       NaN
# d  공기밥  역삼동   30  123-4567
# c  신기해  역삼동   33  123-3333
# b  한국인  신당동   25  123-2222
# a  홍길동  역삼동   23       NaN

print(frame2.sort_index(axis=1, ascending=False))   # axis=1 열을 기준으로 처리, ascending=False DESC로 정렬
#      tel     nai  juso   irum
# a       NaN   23  역삼동  홍길동
# b  123-2222   25  신당동  한국인
# c  123-3333   33  역삼동  신기해
# d  123-4567   30  역삼동  공기밥
# e       NaN   35  신사동  한가해


📌 python DataFrame 데이터 순위 매기기

  • DataFrame rank로 정렬
    - 데이터프레임.rank(axis=0) : 행 기준 사전순으로 순위를 매김
    - 데이터프레임.rank(axis=1) : 열 기준 사전순으로 순위를 매김
print(frame2.rank(axis=0))  # 사전순으로 순위를 매긴다. (먼저 나오는 것이 1.0)
#    irum  juso  nai  tel
# a   5.0   4.0  1.0  NaN
# b   4.0   1.0  2.0  1.0
# c   2.0   4.0  4.0  2.0
# d   1.0   4.0  3.0  3.0
# e   3.0   2.0  5.0  NaN


📌 python DataFrame 전치

  • DataFrame 전치
    - 데이터프레임.T
print(frame2.T) # transpose
#         a         b         c         d    e
# irum  홍길동       한국인       신기해       공기밥  한가해
# juso  역삼동       신당동       역삼동       역삼동  신사동
# nai    23        25        33        30   35
# tel   NaN  123-2222  123-3333  123-4567  NaN


📌 python DataFrame 카테고리별 데이터 개수

  • DataFrame count
    - 데이터프레임['특정 열 이름'].value_counts()
print(frame2['juso'].value_counts())
# 역삼동    3
# 신당동    1
# 신사동    1
# Name: juso, dtype: int64









📊 Pandas DataFrame 산술연산


📌 python DataFrame 산술연산

  • DataFrame 더하기, 빼기, 곱하기, 나누기
    - 더하기 : 데이터프레임1.add(데이터프레임2)
    - 빼기 : 데이터프레임1.sub(데이터프레임2)
    - 곱하기 : 데이터프레임1.mul(데이터프레임2)
    - 나누기 : 데이터프레임1.div(데이터프레임2)
    - fill_value 속성 : 연산 결과로 NaN(결측값) 값이 나오는 구간에 지정한 값으로 채운다.
df1 = pd.DataFrame(np.arange(9).reshape(3,3), columns=list('kbs'), index=['서울','대전','부산'])
df2 = pd.DataFrame(np.arange(12).reshape(4,3), columns=list('kbs'), index=['서울','대전','제주','목포'])
print(df1.add(df2))
#       k    b     s
# 대전  6.0  8.0  10.0
# 목포  NaN  NaN   NaN
# 부산  NaN  NaN   NaN
# 서울  0.0  2.0   4.0
# 제주  NaN  NaN   NaN

print(df1.add(df2, fill_value=0.0))
#       k    b     s
# 대전  6.0  8.0  10.0
# 목포  0.0  0.0   0.0
# 부산  0.0  0.0   0.0
# 서울  0.0  2.0   4.0
# 제주  0.0  0.0   0.0









📊 Pandas DataFrame 통계메소드


📌 python DataFrame 결측치 확인

  • DataFrame isnull() 메소드
    - Null값 True로 변환 : 데이터프레임.isnull()
    - Null값 False로 변환 : 데이터프레임.notnull()

  • 결측치 개수 확인
    - 데이터프레임.isnull().sum()

  • 참고
    - Null이 존재하는 칼럼의 타입이 object이면 Null을 인식하지 못해 개수를 0으로만 출력한다.
    -> 데이터프레임.apply(pd.to_numeric, errors='coerce') 로 해결
    -> 모든 데이터를 숫자형으로 변환
    -> 단순 문자형은 숫자형 변환이 안되므로 해당 값들은 NaN 값으로 처리
print(df.isnull())
#      one    two
# 0  False   True
# 1  False  False
# 2   True   True
# 3  False  False

print(df.notnull())
#      one    two
# 0   True  False
# 1   True   True
# 2  False  False
# 3   True   True


📌 python DataFrame 결측치 제거

  • DataFrame dropna() 메소드
    - Null 삭제 : 데이터프레임.dropna()
    - 한 행에 Null 하나만 있어도 삭제 : 데이터프레임.dropna(how='any')
    - 한 행에 전부 Null이여야만 삭제 : 데이터프레임.dropna(how='all')
    - row 기준 삭제 : 데이터프레임.dropna(axis='rows')
    - column 기준 삭제 : 데이터프레임.dropna(axis='columns')
    - 특정 칼럼 기준 삭제 : 데이터프레임.dropna(subset=['칼럼명1'])
print(df.dropna())
#    one  two
# 1  7.0 -4.5
# 3  0.5 -1.0

print(df.dropna(how='any')) # NaN 값이 있는 행에 NaN값이 하나라도 존재하면 해당 행을 삭제
#    one  two
# 1  7.0 -4.5
# 3  0.5 -1.0

print(df.dropna(how='all')) # NaN 값이 있는 행에 NaN값이 그 행 전체 칼럼에 존재하면 해당 행을 삭제
#    one  two
# 0  1.4  NaN
# 1  7.0 -4.5
# 3  0.5 -1.0

print(df.dropna(axis='rows'))   # row를 기준으로 해당 행에 NaN 값이 존재하면 삭제
#    one  two
# 1  7.0 -4.5
# 3  0.5 -1.0

print(df.dropna(axis='columns'))   # column을 기준으로 해당 열에 NaN 값이 존재하면 삭제
# Empty DataFrame
# Columns: []
# Index: [0, 1, 2, 3]

print(df.dropna(subset=['one']))    # 특정 열에 있는 NaN값이 존재하는 행 삭제
#    one  two
# 0  1.4  NaN
# 1  7.0 -4.5
# 3  0.5 -1.0


📌 python DataFrame 결측치 채우기

  • DataFrame fillna() 메소드
    - Null 채우기 : 데이터프레임.fillna(특정값)
    - 위에 값으로 Null 채우기 : 데이터프레임.fillna(metod='ffill')
    - 아래 값으로 Null 채우기 : 데이터프레임.fillna(metod='bfill')
print(df.fillna(0))
#    one  two
# 0  1.4  0.0
# 1  7.0 -4.5
# 2  0.0  0.0
# 3  0.5 -1.0

print(df.fillna(method='ffill'))    # 앞에(위에) 있는 값으로 NaN값을 대체
#    one  two
# 0  1.4  NaN
# 1  7.0 -4.5
# 2  7.0 -4.5
# 3  0.5 -1.0

print(df.fillna(method='bfill'))    # 뒤에(아래에) 있는 값으로 NaN값을 대체
#    one  two
# 0  1.4 -4.5
# 1  7.0 -4.5
# 2  0.5 -1.0
# 3  0.5 -1.0


📌 python DataFrame 데이터 통계 및 구조 확인

  • DataFrame 데이터 통계 및 구조 확인
    - 요약 통계량 확인(이상치 확인) : 데이터프레임.describe()
    - 데이터 구조 확인(결측치 확인) : 데이터프레임.info()
print(df.describe())    # 데이터프레임 요약 통계량
#             one       two
# count  3.000000  2.000000
# mean   2.966667 -2.750000
# std    3.521837  2.474874
# min    0.500000 -4.500000
# 25%    0.950000 -3.625000
# 50%    1.400000 -2.750000
# 75%    4.200000 -1.875000
# max    7.000000 -1.000000

print(df.info())  		# 데이터프레임 구조
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 4 entries, 0 to 3
# Data columns (total 2 columns):
#  #   Column  Non-Null Count  Dtype  
# ---  ------  --------------  -----  
#  0   one     3 non-null      float64
#  1   two     2 non-null      float64
# dtypes: float64(2)
# memory usage: 192.0 bytes
# None









📊 Pandas DataFrame 데이터 범주화


📌 python DataFrame 칼럼값 범주형으로 변환

  • DataFrame cut() 메소드
    pd.cut(데이터프레임['칼럼1'], bins=[범위1, 범위2, ....], labels=[첫번째 범위값, 두번째 범위값, ....])
    - data 속성 : Series 데이터를 지정 (데이터프레임의 칼럼 인덱싱)
    - bins 속성 : 연속형 데이터를 범주형을 나눌 범위 지정
    - labels 속성 : 특정 범위에 속하는 label 값 지정
cut2 = [1, 500, 1000]
result_cut2 = pd.cut(datas, bins=cut2, labels=[1, 2])
print(result_cut2)
# 0      NaN
# 1        1
# 2        1
# 3        1
# 4        1
#       ... 
# 995      2
# 996      2
# 997      2
# 998      2
# 999      2
# Length: 1000, dtype: category
# Categories (2, int64): [1 < 2]









📊 Pandas DataFrame Join


📌 python DataFrame Join

  • DataFrame merge() 메소드
    pd.merge(왼쪽 데이터프레임, 오른쪽 데이터프레임)
    - how 속성 : Join 방식 지정 ['inner', 'left', 'right', 'outer']
    - on 속성 : Join할 칼럼
    - left_on 속성 : 왼쪽 데이터프레임에서 Join할 칼럼
    - right_on 속성 : 오른쪽 데이터프레임에서 Join할 칼럼
print(pd.merge(df1, df2, on='key')) # key를 기준으로 병합. inner join
#    data1 key  data2
# 0      0   b      1
# 1      1   b      1
# 2      2   b      1
# 3      6   b      1
# 4      4   a      0
# 5      5   a      0

print(pd.merge(df1, df2, on='key', how='inner'))    # key를 기준으로 병합. inner join
#    data1 key  data2
# 0      0   b      1
# 1      1   b      1
# 2      2   b      1
# 3      6   b      1
# 4      4   a      0
# 5      5   a      0


📌 python DataFrame concat

  • DataFrame concat() 메소드
    pd.concat([데이터프레임1, 데이터프레임2])
    - axis 속성 : 로우, 칼럼 기준을 지정
print()
print(pd.concat([df1, df3]))    # 행단위로(아래쪽으로) 이어붙이기. axis=0은 생략
#    data1  key key2  data2
# 0    0.0    b  NaN    NaN
# 1    1.0    b  NaN    NaN
# 2    2.0    b  NaN    NaN
# 3    3.0    c  NaN    NaN
# 4    4.0    a  NaN    NaN
# 5    5.0    a  NaN    NaN
# 6    6.0    b  NaN    NaN
# 0    NaN  NaN    a    0.0
# 1    NaN  NaN    b    1.0
# 2    NaN  NaN    d    2.0

print(pd.concat([df1, df3], axis=1))    # 열단위로(오른쪽으로) 이어붙이기
#    data1 key key2  data2
# 0      0   b    a    0.0
# 1      1   b    b    1.0
# 2      2   b    d    2.0
# 3      3   c  NaN    NaN
# 4      4   a  NaN    NaN
# 5      5   a  NaN    NaN
# 6      6   b  NaN    NaN









📊 Pandas DataFrame 그룹 만들기


📌 python DataFrame groupby

  • DataFrame groupby() 메소드
    - 특정 칼럼으로 그룹화 시켜 새로운 테이블 생성
    - 데이터프레임.groupby(['칼럼명1'])['칼럼명2'].mean()
    - 데이터프레임.groupby(['칼럼명1'])['칼럼명2'].sum()
    - 데이터프레임.groupby(['칼럼명1'])['칼럼명2'].count()
print(df)
#   city  year  pop
# 0   강남  2000  3.3
# 1   강북  2001  2.5
# 2   강남  2002  3.0
# 3   강북  2002  2.0

print(df.groupby(['city']).sum())   # city를 그룹으로 묶어 합을 구한다.
#       year  pop
# city           
# 강남    4002  6.3
# 강북    4003  4.5

print(df.groupby(['city','year']).mean())   # 우선 city로 그룹화 시키고, 이후 year로 그룹화 시켜 평균을 구한다.
# city  year     
# 강남   2000  3.3
#       2002  3.0
# 강북   2001  2.5
#       2002  2.0









📊 Pandas DataFrame 데이터 읽기, 저장


📌 python DataFrame 데이터 읽기

  • **DataFrame read파일명() 메소드_
    _
    - csv파일 GET : pd.readcsv("파일경로")
    _
    - header 속성 :** 칼럼이 존재여부에 따라 True or False 지정_
df = pd.read_csv("../testdata/ex1.csv")
print(df, type(df))
#      bunho irum  kor  eng
# 0      1  홍길동   90   90
# 1      2  신기해   95   80
# 2      3  한국인  100   85
# 3      4  박치기   67   54
# 4      5  마당쇠   55  100 <class 'pandas.core.frame.DataFrame'>

df2 = pd.read_csv("../testdata/ex2.csv", header=None, names=list('korea'))
print(df2)
#    k   o   r   e      a
# 0  1   2   3   4  hello
# 1  5   6   7   8  world
# 2  9  10  11  12    foo


📌 python DataFrame 데이터 저장

  • DataFrame to_csv()
    - csv파일 Write : pd.to_csv("파일명")
    - index 속성 : 인덱스 값 존재 여부를 결정
    - header 속성 : 칼럼명 존재 여부를 결정
df.to_csv("result1.csv")
df.to_csv("result2.csv", index=False)
df.to_csv("result3.csv", index=False, header=False)


profile
데이터 사이언티스트를 목표로 하는 개발자

0개의 댓글