본문 바로가기

AI인공지능 by Python/3. 데이터 분석

[ AI 인공지능 ] ② 판다스(Pandas) _ 1

1. Pandas

  • '웨스 맥키니'가 개발한 라이브러리
  • 데이터 작업을 쉽고 직관적으로 할 수 있도록, 설계된 빠르고 유연한 데이터 구조를 제공하는 모듈
!pip install pandas

import pandas as pd

pd

> <module 'pandas' from '/usr/local/lib/python3.9/dist-packages/pandas/__init__.py'>

 

1-1. Series와 DataFrame

  • 시리즈 : 1차원, 1개의 column
  • 데이터프레임 : 가로축, 세로축이 있는 2차원의 다양한 타입 데이터를 저장하는 자료구조
pd.Series([1,2,3,4])

> 0    1
   1    2
   2    3
   3    4
dtype: int64

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

> 0    1
   1    2
   2    3
   3    4
dtype: int64

 

 ✔️리스트를 통해 데이터프레임 만들기

ex)) 임의의 숫자일 뿐입니다!

product1 = [['삼성', 990000, '갤럭시23'],
            ['애플', 1500000, '맥북에어'],
            ['엘지', 600000, '공기청정기']]
            
product1

> [['삼성', 990000, '갤럭시23'], ['애플', 1500000, '맥북에어'], ['엘지', 600000, '공기청정기']]

pd.DataFrame(product1)
  0 1 2
0 삼성 990000 갤럭시23
1 애플 1500000 맥북에어
2 앨지 600000 공기청정기

 

df1 = pd.DataFrame(product1)

df1
  0 1 2
0 삼성 990000 갤럭시23
1 애플 1500000 맥북에어
2 앨지 60000 공기청정기
df1.columns = ['회사명', '가격', '상품명']

df1
  회사명 가격 상품명
0 삼성 990000 갤럭시23
1 애플 1500000 맥북에어
2 앨지 600000 공기청정기

 

✔️ 딕셔너리를 통한 데이터프레임 만들기

product2 = {
    '회사명': ['삼성','애플','엘지'],
    '가격' : [900000, 1500000, 600000],
    '상품명' : ['갤럭시23', '맥북에어', '공기청정기']
}

df2 = pd.DataFrame(product2)

df2
  회사명 가격 삼품명
0 삼성 990000 갤럭시23
1 애플 1500000 맥북에어
2 앨지 600000 공기청정기

 

df2['상품명']

> 0    갤럭시23
   1     맥북에어
   2    공기청정기
Name: 상품명, dtype: object

type(df2['상품명'])

> pandas.core.series.Series

 

2. CSV 파일

  • Comma Seperated Value의 약자로써 데이터를 쉼표로 구분한 파일
  • 엑셀로 로딩할 수 있지만, 쉼표로 구분된 파일이 더욱 가볍기 때문에 표준 csv를 많이 사용
  • 공공데이터 포탈에서도 csv 포멧의 파일을 많이 제공(https://www.data.go.kr/)
# pd.read_csv('전국도시공원표준데이터.csv')
pd.read_csv('전국도시공원표준데이터.csv', encoding = 'cp949')

pd.read_csv('http://bit.ly/ds-korean-idol')

pd.read_csv('/content/drive/MyDrive/파이썬_AI인공지능/3. 데이터분석/korean-idol.csv')
  • 표가 뜰 것이다! but 생략

 

3. 엑셀파일 읽어오기

pd.read_excel('/content/drive/MyDrive/파이썬_AI인공지능/3. 데이터분석/korean-idol.xlsx')
  • 표가 뜰 것이다! but 생략

 

4. 데이터 기본정보 알아보기

df = pd.read_csv('http://bit.ly/ds-korean-idol')

df
  이름 그룹 소속사 성별 생년월일 혈액형 브랜드평판지수
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260
1 지드래곤 빅뱅 YG 남자 1988-08-18 177 A 9916947
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745
3 방탄소년단 빅히트 남자 1995-12-30 178 AB 8073501
4 화사 마마무 RBW 여자 1995-07-23 162.1 A 7650928
5 정국 방탄소년단 빅히트 남자 1997-09-01 178 A 5208335
6 민현 뉴이스트 플레디스 남자 1995-08-09 182.3 O 4989792
7 소연 아이들 큐브 여자 1998-08-26 NaN B 4668615
8 방탄소년단 빅히트 남자 1992-12-04 179.2 O 4570308
9 하성운 핫샷 스타크루이엔티 남자 1994-03-22 167.1 A 4036489
10 태연 소녀시대 SM 여자 1989-03-09 NaN A 3918661
11 차은우 아스트로 판타지오 남자 1997-03-30 183 B 3506027
12 백호 뉴이스트 플레디스 남자 1995-07-21 175 AB 3301654
13 JR 뉴이스트 플레디스 남자 1995-06-08 176 O 3274137
14 슈가 방탄소년단 빅히트 남자 1993-03-09 174 O 2925442
type(df)

> pandas.core.frame.DataFrame

 

4-1. 열(column)

df.columns # 데이터프레임에서 dtype = 'object'는 문자열

> Index(['이름', '그룹', '소속사', '성별', '생년월일', '키', '혈액형', '브랜드평판지수'], dtype='object')

new_column = ['name', 'group', 'company', 'gender', 'birthday', 'height', 'blood', 'brand']

df.columns = new_column

df.columns

> Index(['name', 'group', 'company', 'gender', 'birthday', 'height', 'blood', 'brand'], dtype='object')

df
  name group company gender birthday height blood brand
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260
1 지드래곤 빅뱅 YG 남자 1988-08-18 177 A 9916947
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745
3 방탄소년단 빅히트 남자 1995-12-30 178 AB 8073501
4 화사 마마무 RBW 여자 1995-07-23 162.1 A 7650928
5 정국 방탄소년단 빅히트 남자 1997-09-01 178 A 5208335
6 민현 뉴이스트 플레디스 남자 1995-08-09 182.3 O 4989792
7 소연 아이들 큐브 여자 1998-08-26 NaN B 4668615
8 방탄소년단 빅히트 남자 1992-12-04 179.2 O 4570308
9 하성운 핫샷 스타크루이엔티 남자 1994-03-22 167.1 A 4036489
10 태연 소녀시대 SM 여자 1989-03-09 NaN A 3918661
11 차은우 아스트로 판타지오 남자 1997-03-30 183 B 3506027
12 백호 뉴이스트 플레디스 남자 1995-07-21 175 AB 3301654
13 JR 뉴이스트 플레디스 남자 1995-06-08 176 O 3274137
14 슈가 방탄소년단 빅히트 남자 1993-03-09 174 O 2925442

 

4-2. 행(row)

df.index

> RangeIndex(start=0, stop=15, step=1)

 

✔️ info : 기본적인 행(row)의 정보와 데이터 타입을 변환

df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15 entries, 0 to 14
Data columns (total 8 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   name      15 non-null     object 
 1   group     14 non-null     object 
 2   company   15 non-null     object 
 3   gender    15 non-null     object 
 4   birthday  15 non-null     object 
 5   height    13 non-null     float64
 6   blood     15 non-null     object 
 7   brand     15 non-null     int64  
dtypes: float64(1), int64(1), object(6)
memory usage: 1.1+ KB

 

4-3. 통계정보 알아보기

✔️ describe() : 정수 또는 실수의 필드 데이터만 가져와서 통계정보를 출력

df.describe()
  height  brand
count 13.000000 1.500000e+01
mean 175.792308  5.655856e+06
std  5.820576  2.539068e+06
min 162.100000  2.925442e+06
25% 174.000000  3.712344e+06
50% 177.000000 4.668615e+06
75% 179.200000 7.862214e+06
max 183.000000 1.052326e+07

 

4-4. 형태(shape) 알아보기

df.shape
# (행, 열)

> (15, 8)

 

4-5. 원하는 개수의 데이터 보기

  • head() : 상위 5개의 row 출력
  • head(n) : 상위 n개의 row 출력
  • tail() : 하위 5개의 row 출력
  • tail(n) : 하위 n개의 row 출력
df.head()
  name group company gender birthday height blood brand
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260
1 지드래곤 빅뱅 YG 남자 1988-08-18 177 A 9916947
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745
3 방탄소년단 빅히트 남자 1995-12-30 178 AB 8073501
4 화사 마마무 RBW 여자 1995-07-23 162.1 A 7650928
df.head(3)
  name group company gender birthday height blood brand
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260
1 지드래곤 빅뱅 YG 남자 1988-08-18 177 A 9916947
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745
# 해보기
df.tail()
df.tail(3)

 

4-6. 정렬하기

✔️ 인덱스로 오름차순 정렬

df.sort_index()

✔️ 인덱스로 내림차순 정렬

df.sort_index(ascending = False)

✔️ 에 따른 오름차순 정렬

df.sort_values(by = 'height')

✔️ 에 따른 내림차순 정렬

▪️ na_position = 'last' 기본값

-> NaN을 가장 밑으로 내린다 

df.sort_values(by = 'height', ascending = False)

▪️ NaN을 가장 위로 올림

df.sort_values(by = 'height', ascending = False, na_position = 'first')

✔️ 1차 정렬 : 키(내림차순)

       2차 정렬 : 브랜드(내림차순)

df.sort_values(by = ['height', 'brand'], ascending = [False, True], na_position = 'first')

 

5. 컬럼으로 데이터 다루기

df['blood']

0      A
1      A
2      A
3     AB
4      A
5      A
6      O
7      B
8      O
9      A
10     A
11     B
12    AB
13     O
14     O
Name: blood, dtype: object

type(df['blood'])

> pandas.core.series.Series

df['name']

0       지민
1     지드래곤
2     강다니엘
3        뷔
4       화사
5       정국
6       민현
7       소연
8        진
9      하성운
10      태연
11     차은우
12      백호
13      JR
14      슈가
Name: name, dtype: object

df.name

0       지민
1     지드래곤
2     강다니엘
3        뷔
4       화사
5       정국
6       민현
7       소연
8        진
9      하성운
10      태연
11     차은우
12      백호
13      JR
14      슈가
Name: name, dtype: object

 

5-1. 범위 선택

df[:3] # df.head(3)
  name group company gender birthday height blood brand
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260
1 지드래곤 빅뱅 YG 남자 1988-08-18 177 A 9916947
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745
df.loc[:, 'name']

0       지민
1     지드래곤
2     강다니엘
3        뷔
4       화사
5       정국
6       민현
7       소연
8        진
9      하성운
10      태연
11     차은우
12      백호
13      JR
14      슈가
Name: name, dtype: object

 

 ✔️ 인덱스가 아니기 때문에 5번까지 즉, 5번을 포함하여 가져온다

df.loc[:5, 'name']

0      지민
1    지드래곤
2    강다니엘
3       뷔
4      화사
5      정국
Name: name, dtype: object

df.loc[:, ['name', 'gender', 'height']]
  name gender height
0 지민 남자 173.6
1 지드래곤 남자 177
2 강다니엘 남자 180
3 남자 178
4 화사 여자 162.1
5 정국 남자 178
6 민현 남자 182.3
7 소연 여자 NaN
8 남자 179.2
9 하성운 남자 167.1
10 태연 여자 NaN
11 차은우 남자 183
12 백호 남자 175
13 JR 남자 176
14 슈가 남자 174
df.loc[3:8, ['name','gender','height']]
  name gender height
3 남자 178
4 화사 여자 162.1
5 정국 남자 178
6 민현 남자 182.3
7 소연 여자 NaN
8 남자 179.2
df.loc[3:8, 'name':'birthday']
  name group company gender birthday
3 방탄소년단 빅히트 남자 1995-12-30
4 화사 마마무 RBW 여자 1995-07-23
5 정국 방탄소년단 빅히트 남자 1997-09-01
6 민현 뉴이스트 플레디스 남자 1995-08-09
7 소연 아이들 큐브 여자 1998-08-26
8 방탄소년단 빅히트 남자 1992-12-04
df.iloc[:, [0, 2]]
  name company

0
지민 빅히트
1 지드래곤 YG
2 강다니엘 커넥트
3 빅히트
4 화사 RBW
5 정국 빅히트
6 민현 플레디스
7 소연 큐브
8 빅히트
9 하성운 스타크루이엔티
10 태연 SM
11 차은우 판타지오
12 백호 플레디스
13 JR 플레디스
14 슈가 빅히트

✔️  0:2 => index 2를 포함하지 않음

df.iloc[:, 0:2]
  name group
0 지민 방탄소년단
1 지드래곤 빅뱅
2 강다니엘 NaN
3 방탄소년단
4 화사 마마무
5 정국 방탄소년단
6 민현 뉴이스트
7 소연 아이들
8 방탄소년단
9 하성운 핫샷
10 태연 소녀시대
11 차은우 아스트로
12 백호 뉴이스트
13 JR 뉴이스트
14 슈가 방탄소년단
df.iloc[0:3, 0:2]
  name group
0 지민 방탄소년단
1 지드래곤 빅뱅
2 강다니엘 NaN

 

6. Boolean Indexing

df['height'] >= 180

0     False
1     False
2      True
3     False
4     False
5     False
6      True
7     False
8     False
9     False
10    False
11     True
12    False
13    False
14    False
Name: height, dtype: bool

df[df['height'] >= 180]
  name group company gender birthday height blood brand
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745
6 민현 뉴이스트 플레디스 남자 1995-08-09 182.3 O 4989792
11 차은우 아스트로 판타지오 남자 1997-03-30 183 B 3506027
df[df['height'] >= 180]['name']

2     강다니엘
6       민현
11     차은우
Name: name, dtype: object

df[df['height'] >= 180][['name','birthday','blood']]
  name birthday blood
2 강다니엘 1996-12-10 A
6 민현 1995-08-09 O
11 차은우 1997-03-30 B
df.loc[df['height'] >= 180, ['name','birthday','height']]
  name birthday height
2 강다니엘 1996-12-10 180
6 민현 1995-08-09 182.3
11 차은우 1997-03-30 183

 

7. isin 활용하기

  • isin은 조건을 걸고자 하는 값이 정의한 list에 있을 때만 색인하려는 경우에 사용
company = ['플레디스', 'SM']

df['company'].isin(company)

0     False
1     False
2     False
3     False
4     False
5     False
6      True
7     False
8     False
9     False
10     True
11    False
12     True
13     True
14    False
Name: company, dtype: bool

df[df['company'].isin(company)]
  name group company gender birthday height blood brand
6 민현 뉴이스트 플레디스 남자 1995-08-09 182.3 O 4989792
10 태연 소녀시대 SM 여자 1989-03-09 NaN A 3918661
12 백호 뉴이스트 플레디스 남자 1995-07-21 175 AB 3301654
13 JR 뉴이스트 플레디스 남자 1995-06-08 176 O 3274137
df.loc[df['company'].isin(company), 'name':'company']
  name group company
6 민현 뉴이스트 플레디스
10 태연 소녀시대 SM
12 백호 뉴이스트 플레디스
13 JR 뉴이스트 플레디스

 

8. 결측값(Null)

  • Null은 비어있는 값 또는 결측값이라고 부름
  • pandas에서는 NaN(Not a Number)로 표기된 것은 모두 결측값으로 취급

✔️ 결측값인지 아닌지 여부를 판단

df.isna()
  name group company gender birthday height blood brand
0 False False False False False False False False
1 False False False False False False False False
2 False True False False False False False False
3 False False False False False False False False
4 False False False False False False False False
5 False False False False False False False False
6 False False False False False False False False
7 False False False False False True False False
8 False False False False False False False False
9 False False False False False False False False
10 False False False False False True False False
11 False False False False False False False False
12 False False False False False False False False
13 False False False False False False False False
14 False False False False False False False False

✔️  null인지 아닌지 여부를 판단

df.isnull()

-> 위와 같은 값

df['group'].isnull()

0     False
1     False
2      True
3     False
4     False
5     False
6     False
7     False
8     False
9     False
10    False
11    False
12    False
13    False
14    False
Name: group, dtype: bool

df[df['group'].isnull()]
  name group company gender birthday height blood brand
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745

 

df[df['group'].isnull()]['name']

2    강다니엘
Name: name, dtype: object

df['name'][df['group'].isnull()]

2    강다니엘
Name: name, dtype: object

df['name'][df['group'].notnull()]

0       지민
1     지드래곤
3        뷔
4       화사
5       정국
6       민현
7       소연
8        진
9      하성운
10      태연
11     차은우
12      백호
13      JR
14      슈가
Name: name, dtype: object

 

☑️  문제

그룹이 있는 연예인의 이름, 키, 혈액형을 출력(단, loc 사용)

df.loc[df['group'].notnull(), ['name','height','blood']]
  name height blood
0 지민 173.6 A
1 지드래곤 177 A
3 178 AB
4 화사 162.1 A
5 정국 178 A
6 민현 182.3 O
7 소연 NaN B
8 179.2 O
9 하성운 167.1 A
10 태연 NaN A
11 차은우 183 B
12 백호 175 AB
13 JR 176 O
14 슈가 174 O