Posts 판다스(Pandas) 기초(1)
Post
Cancel

판다스(Pandas) 기초(1)

1. 판다스(Pandas)


1.1 판다스(Pandas)란?

  • 데이터 분석을 위한 사용이 쉽고 성능이 좋은(numpy로 작성됨) 오픈소스(공개된) python 라이브러리(파이썬으로만 사용가능)
  • R과 Pandas의 차이점
    • R보다 Pandas가 학습이 쉽습니다.
    • R보다 Pandas가 성능이 좋습니다.
    • R보다 Python은 활용할수 있는 분야가 많습니다.
  • 크게 두가지 데이터 타입을 사용합니다.
    • Series : index와 value로 이루어진 데이터 타입, Value는 동일한 데이터 타입을 가져야함
    • DataFrame : index, column, value로 이루어진 데이터 타입(테이블형태) column 데이터는 Series, Series들이 모여서 DataFrame이 됨
1
import pandas as pd
  • 판다스는 pd라는 약어로 자주 사용된다.


2. Series


2.1 Series란

  • 동일한 데이터 타입의 값을 가짐
  • value만 설정하면 index는 자동으로 0부터 설정됨

2.2 Series 기초

2.2.1 Series 생성

1
2
data = pd.Series(np.random.randint(10, size = 5))
data
1
2
3
4
5
6
0    6
1    4
2    6
3    4
4    0
dtype: int64
  • pd.Series 메서드를 활용하여 Series를 생성 할수 있다.
  • Series에서 S는 대문자이다.


2.2.2 Index 생성

1
2
data = pd.Series(np.random.randint(10, size=5), index=list('ABCDE'))
data
1
2
3
4
5
6
A    1
B    9
C    9
D    5
E    4
dtype: int64
  • index 설정하는 법, Series 생성시 index = index 값으로 주면된다.


2.2.3 Index 활용

1
data.index, data.values
1
(Index(['A', 'B', 'C', 'D', 'E'], dtype='object'), array([5, 7, 0, 3, 5]))
  • data.index 하면 index를 보여준다.


1
data['B']
1
9
  • data에 index로 마스킹 하여 데이터 값을 확인 가능


1
data.B
1
9
  • index로 데이터 확인


1
2
data['C'] = 10
data
1
2
3
4
5
6
A     5
B     7
C    10
D     3
E     5
dtype: int64
  • index로 데이터를 불러와, 다른값(10)으로 변경도 가능함


1
data[['B','E']]
1
2
3
B    9
E    4
dtype: int64
  • index를 여러개 지정하여 출력도 가능


2.2.4 Offset index

1
data[2]
1
9
  • iterable[index]


1
data[1:4]
1
2
3
4
B    9
C    9
D    5
dtype: int64
  • iterable[start:end]


1
data[0:4:2]
1
2
3
A    1
C    9
dtype: int64
  • iterable[start : end: stride] ( stride는 보폭, 간격 이라고 생각하면 된다.)


1
data[::-1]
1
2
3
4
5
6
E    4
D    5
C    9
B    9
A    1
dtype: int64
  • iterable[::-1] : 역순으로 출력


  • Series도 Offset index를 사용가능함
  • 문자열을 작성하게되면 각 문자마다 고유의 번호가 매겨지는데 이 번호를 오프셋이라 함,
  • 오프셋을 이용하여 문자열에서 문자를 추출하는 것을 인덱싱이라 함

2.2.5 브로드 캐스팅

1
data * 10
1
2
3
4
5
6
A    10
B    90
C    90
D    50
E    40
dtype: int64
  • 브로드캐스팅이란 배열에서 차원의 크기가 서로 다른 배열에서도 산술 연산을 가능하게 하는 원리
  • Series도 브로드 캐스팅 개념이 있음
  • data의 모든 value에 10을 곱해줄수 있음


2.3 Serise 연산

1
data
1
2
3
4
5
6
A    1
B    9
C    9
D    5
E    4
dtype: int64
1
2
data2 = pd.Series({'D' : 3, 'E' : 5, 'F' : 7})
data2
1
2
3
4
D    3
E    5
F    7
dtype: int64
1
2
result = data + data2
result
1
2
3
4
5
6
7
A    NaN
B    NaN
C    NaN
D    8.0
E    9.0
F    NaN
dtype: float64
  • Series는 같은 index끼리 더해짐으로 양쪽애 같은 index가 없는 데이터는 NaN으로 나옴


2.4 Nan 데이터를 기존의 데이터에 넣어주는법

1
2
result[result.isnull()] = data 
result
1
2
3
4
5
6
7
A     5.0
B     7.0
C    10.0
D     6.0
E    10.0
F     NaN
dtype: float64
  • isnull : 데이터가 NaN값이면 True를 반환하는 메서드
  • result에 isnull 메서드를 사용하여 True로 만든 뒤 : result.isnull()
  • result로 마스킹을 해주어 True값만 가져온다. result[result.isnull()] 하면 NaN값만 반환됨
  • 위에서 반환된 NaN값은 data 값이라고 명시해주면 된다.


1
2
result[result.isnull()] = data2
result
1
2
3
4
5
6
7
A     5.0
B     7.0
C    10.0
D     6.0
E    10.0
F     7.0
dtype: float64
  • 위와 같은 방법으로 data2의 F의 index 값도 넣어줌


3. DataFrame


3.1 DataFrame이란?

  • 데이터 프레임은 여러개의 Series로 구성
  • 같은 컬럼에 있는 value값은 같은 데이터 타입을 가짐


3.2 DataFrame 기초

3.2.1 데이터 프레임 생성 (1)

1
2
3
4
5
datas = {
    'name' : ['dss', 'fcamp'],
    'email' : ['dss@gmail.com', 'fcamp@daum.net']
}
datas
1
{'name': ['dss', 'fcamp'], 'email': ['dss@gmail.com', 'fcamp@daum.net']}
1
2
df = pd.DataFrame(datas)
df
nameemail
0dssdss@gmail.com
1fcampfcamp@daum.net
  • 딕셔너리의 리스트 (딕셔너리의 value값에 리스트가 있음)
  • 딕셔너리의 키값은 컬럼으로 잡히고, 벨류값은 데이터로 인식되게 됨


3.2.2 데이터 프레임 생성 (2)

1
2
3
4
5
datas =[
    {'name' : 'dss', 'email' : 'dss@gmail.com'},
    {'name': 'fcamp', 'email' : 'fcamp@daum.net'}
]
datas
1
2
[{'name': 'dss', 'email': 'dss@gmail.com'},
 {'name': 'fcamp', 'email': 'fcamp@daum.net'}]
1
2
df = pd.DataFrame(datas)
df
nameemail
0dssdss@gmail.com
1fcampfcamp@daum.net
  • 리스트 안에 딕셔너리
  • 딕셔너리의 키값은 컬럼, 벨류값은 데이터 값
  • 단점은 하나의 딕셔너리가 하나의 행으로 만들어져서 큰 데이터를 만들기에는 조금 번거로움


3.2.3 index

1
2
df = pd.DataFrame(datas, index = ['one', 'two'])
df
nameemail
onedssdss@gmail.com
twofcampfcamp@daum.net
  • index = [] 값으로 추가 가능


1
df.index
1
Index(['one', 'two'], dtype='object')
  • index값을 불러옴


3.2.4 Columns, Value

1
df.columns
1
Index(['name', 'email'], dtype='object')
  • 데이터프레임.columns 메서드로 column들을 불러옴
  • 해당 메서드는 생각보다 쓸모가 많음


1
df.values
1
2
array([['dss', 'dss@gmail.com'],
       ['fcamp', 'fcamp@daum.net']], dtype=object)
  • 데이터프레임.value 메서드로 value값을 불러옴, 다만 데이터가 많을때는 그닥 추천하는 방법은 아님


3.3 Data Frame에서 데이터의 선택

3.3.1 Row 선택

1
2
3
4
5
6
7
8
datas = [
    # 딕셔너리 1개는 1row, 딕셔너리의 key는 colum, value는 값
    {"name": "dss", "email": "dss@gmail.com"},
    # 딕셔너리 1개는 1row, 딕셔너리의 key는 colum, value는 값
    {"name": "fcamp", "email": "fcamp@daum.net"}
]
df = pd.DataFrame(datas)
df
nameemail
0dssdss@gmail.com
1fcampfcamp@daum.net
  • 리스트안에 딕셔너리 방식으로 데이터프레임 생성


1
df.loc[1]
1
2
3
name              fcamp
email    fcamp@daum.net
Name: 1, dtype: object
  • row data 선택, series 데이터가 나옴


1
df.loc[1]['email']
1
'fcamp@daum.net'
  • row data 선택, series 데이터가 나옴
  • 뒤에 컬럼명을 마스킹 해주면 특정 컬럼만 가져올수 있음


1
2
df.loc[2] = {"name" : "andy", "email" : "andy@naver.com"}
df
nameemail
0dssdss@gmail.com
1fcampfcamp@daum.net
2andyandy@naver.com
  • loc[2] index가 있으면 수정되며, 없으면 추가 됨


3.3.2 Column 선택

1
df['name']
1
2
3
4
0      dss
1    fcamp
2     andy
Name: name, dtype: object
  • 데이터프레임[컬럼명] 으로 원하는 컬럼만 선택가능
  • 시리즈 형식으로 출력됨


1
2
df['id'] = ''
df
nameemailid
0dssdss@gmail.com
1fcampfcamp@daum.net
2andyandy@naver.com
  • 데이터프레임[없는 컬럼명] = ‘’ 을 하면 column이 생성되고, 빈값(결측치 아님)이 들어감.
  • 브로드 캐스팅되며 원하는 값이 있다면 넣어주어도 된다.


1
2
df['id'] = range(1,4)
df
nameemailid
0dssdss@gmail.com1
1fcampfcamp@daum.net2
2andyandy@naver.com3
  • 없던 컬럼 값을 생성하면 추가됨
  • 원래 있던 컬럼을 선택하면 수정


1
df.dtypes
1
2
3
4
name     object
email    object
id        int64
dtype: object
  • 데이터프레임.dtype으로 column별 데이터 타입 확인
  • object는 데이터 타입의 상위 객체


3.3.3 Row, Column 선택

1
df.loc[[0, 2], ['email', 'id']]
emailid
0dss@gmail.com1
2andy@naver.com3
  • 데이터프레임의 0번쨰, 2번째 행을 선택하고 그중 email과 id 컬럼만 선택하는 코드
  • 2번 마스킹 해주어야 함


3.3.4 Column의 순서 변경

1
df[['id', 'name', 'email']]
idnameemail
01dssdss@gmail.com
12fcampfcamp@daum.net
23andyandy@naver.com
  • 두개 이상의 컬럼 선택시 리스트 데이터 타입으로, 쓴 순서대로 컬럼명이 정렬되어 나옴


3.5 데이터 미리보기

3.5.1 Head

1
df.head()
nameemailid
0dssdss@gmail.com1
1fcampfcamp@daum.net2
2andyandy@naver.com3
  • 데이터프레임.head(n) 하면 앞에서 n개 만큼 데이터를 보여줌
  • 디폴트 n은 5


3.5.2 Tail

1
df.tail()
nameemailid
0dssdss@gmail.com1
1fcampfcamp@daum.net2
2andyandy@naver.com3
  • 데이터프레임.tail(n) 하면 뒤에서 n개 만큼 데이터를 보여줌
  • 디폴트 n은 5
  • 뒤의 데이터를 보기 때문에 해당 데이터가 몇개 인지 확인할수 있음


3.5.3 Shape

1
df.shape
1
(3, 3)
  • shape메서드는 데이터의 크기 확인, 보통 분석시 merge나 join, duplicated(중복제거) 등을 사용할때 확인함


3.6 apply 함수

1
2
3
4
def domain(email):
    return email.split('@')[1].split('.')[0]

domain(df.loc[0]['email'])
1
'gmail'
  • email에서 도메인만 찾는 함수를 작성


1
2
df['domain'] = df['email'].apply(domain)
df
nameemailiddomain
0dssdss@gmail.com1gmail
1fcampfcamp@daum.net2daum
2andyandy@naver.com3naver
  • map 함수와 비슷한 역할이며, apply를 사용하여 각 행에 함수를 적용함
  • 위의 코드는 email 컬럼에서 메일의 도메인만 가져와서 새로운 domain 컬럼을 생성하는 코드임


3.7 Append

1
2
3
from makedata import *
df1 = pd.DataFrame(make_data(5))
df2 = pd.DataFrame(make_data(5))
  • makedata는 age와 name을 랜덤하게 생성해주는 모듈
  • 따로 만든것이므로, 실제 파이썬에서 제공되는 모듈은 아님


1
2
df3 = df1.append(df2)
df3
AgeName
028Alan
129Anchal
235Anchal
332Billy
425Arnold
037Jin
134Alvin
221Andrew
328Arnold
432Anthony
  • append 메서드를 활용하여 데이터 프레임 합치기
  • df1.append(df2)를 하면 df1 아래에 df2가 합쳐지게 된다.
  • offset index사용 가능


3.8 Reset_index

1
df3.reset_index()
indexAgeName
0028Alan
1129Anchal
2235Anchal
3332Billy
4425Arnold
5037Jin
6134Alvin
7221Andrew
8328Arnold
9432Anthony
  • reset_index 메서드를 사용하여 인덱스 재정렬
  • 기존에 있던 index가 컬럼으로 바뀌면서 새로운 컬럼으로 생성이됨


1
df3.reset_index(drop = True)
AgeName
028Alan
129Anchal
235Anchal
332Billy
425Arnold
537Jin
634Alvin
721Andrew
828Arnold
932Anthony
  • drop = True 옵션을 주어 기존의 index를 컬럼으로 따로 저장하지 않음


1
df3
AgeName
028Alan
129Anchal
235Anchal
332Billy
425Arnold
037Jin
134Alvin
221Andrew
328Arnold
432Anthony
  • 하지만 자동으로 저장이 되진 않음
  • 자세히 보면 index가 그대로 0123401234 인것임을 볼수있음 저장이 안된것


1
2
df3.reset_index(drop = True, inplace= True)
df3
AgeName
028Alan
129Anchal
235Anchal
332Billy
425Arnold
537Jin
634Alvin
721Andrew
828Arnold
932Anthony
  • 저장을 위해 Inplace = True 옵션을 주어야함


1
2
df3 = df1.append(df2, ignore_index= True)
df3
AgeName
028Alan
129Anchal
235Anchal
332Billy
425Arnold
537Jin
634Alvin
721Andrew
828Arnold
932Anthony
  • reset_index를 사용하지 않고 append로 데이터 프레임을 합칠때 ignore_index = True의 옵션을 주어 index를 생성할수 있음


3.9 Concat

1
2
df3 = pd.concat([df1, df2])
df3
AgeName
028Alan
129Anchal
235Anchal
332Billy
425Arnold
037Jin
134Alvin
221Andrew
328Arnold
432Anthony
  • row나 column으로 데이터 프레임을 합칠때 사용
  • 위의 코드는 row로 합쳐지는 것(디폴트)
  • append보다 기능이 더 많음


1
2
df3 = pd.concat([df1, df2]).reset_index(drop=True)
df3
AgeName
028Alan
129Anchal
235Anchal
332Billy
425Arnold
537Jin
634Alvin
721Andrew
828Arnold
932Anthony
  • concat뒤에 .reset_index를 사용하여 바로 index를 재설정 할수 있음


1
pd.concat([df3, df1], axis = 1)
AgeNameAgeName
028Alan28.0Alan
129Anchal29.0Anchal
235Anchal35.0Anchal
332Billy32.0Billy
425Arnold25.0Arnold
537JinNaNNaN
634AlvinNaNNaN
721AndrewNaNNaN
828ArnoldNaNNaN
932AnthonyNaNNaN
  • Column에 추가 하는 방법은 axis = 1 옵션을 주면됨
  • 위의 경우엔 outer로 join되어 5 ~ 9 index는 Nan값이 나옴


1
pd.concat([df3, df1], axis = 1, join='inner')
AgeNameAgeName
024Billy24Billy
135Alan35Alan
237Alan37Alan
336Arnold36Arnold
429Alex29Alex
  • join = inner 옵션을 주어 Nan 값은 join안되게 만들수 있음


3.10 Group by

1
2
df = pd.DataFrame(make_data())
df
AgeName
026Billy
122Jin
226Anthony
325Andrew
437Alan
522Alex
630Alan
736Anthony
827Adam
920Billy
  • 실습용 데이터 생성
  • 특정 컬럼의 중복되는 데이터를 합쳐서 새로운 데이터 프레임을 만드는 방법
  • group by를 사용하면 name의 중복되는 데이터를 합쳐서 age의 평균, 중앙, 최소, 최대값 등을 볼수 있음
  • Ex : 이름별 평균 나이


1
df.groupby('Name').size()
1
2
3
4
5
6
7
8
9
Name
Adam       1
Alan       2
Alex       1
Andrew     1
Anthony    2
Billy      2
Jin        1
dtype: int64
  • groupby(‘Name’).size()로 이름의 중복을 제거하고 몇개가 중복이었는지 size를 (count)를 하는것


1
df.groupby("Name").size().reset_index()
Name0
0Adam1
1Alan2
2Alex1
3Andrew1
4Anthony2
5Billy2
6Jin1
  • groupby size
  • name은 index, 1,2등의 숫자는 value값으로, reset_index의 함수를 이용하여 DataFrame을 생성함
  • reset_index의 기존 인덱스는 컬럼으로 재 생성하는 원리를 이용함


1
2
result_df = df.groupby("Name").size().reset_index(name = "count")
result_df
Namecount
0Adam1
1Alan2
2Alex1
3Andrew1
4Anthony2
5Billy2
6Jin1
  • Name 옆의 0 컬럼의 이름을 변경하기 위해 reset_index에서 name 옵션을 주었음


1
result_df.sort_values(['count'])
Namecount
0Adam1
2Alex1
3Andrew1
6Jin1
1Alan2
4Anthony2
5Billy2
  • sort_values : 설정한 컬럼으로 데이터 프레임을 정렬
  • count를 오름차순으로 정렬(디폴트)


1
result_df.sort_values(['count'], ascending= False)
Namecount
1Alex4
4Billy3
0Alan1
2Anthony1
3Arnold1
  • 만일 내림차순으로 하고 싶다면, acsending = False 옵션을 주면됨


1
result_df.sort_values(['count'], ascending= False, inplace= True)
  • 자동 저장이 안되기 때문에 inplace = True 옵션을 줌


1
2
result_df.reset_index(drop = True, inplace = True)
result_df
Namecount
0Adam1
1Alan2
2Alex1
3Andrew1
4Anthony2
5Billy2
6Jin1
  • index순서 정리 후 inplace로 저장


3.10.1 agg() 을 사용하면 데이터 프레임으로 결과가 출력됨

1
df.groupby('Name').agg('min').reset_index()
NameAge
0Alan36
1Alex23
2Anthony30
3Arnold20
4Billy36
  • size(), min(), max(), mean() 등의 함수를 쓸 수 있음


3.11 Decsribe()

1
df.describe()
Age
count10.000000
mean27.100000
std5.724218
min20.000000
25%22.750000
50%26.000000
75%29.250000
max37.000000
  • 데이터의 기술통계치를 요약해서 보여주는 함수
This post is licensed under CC BY 4.0 by the author.