반응형

[Python, 데이터분석] 파이썬 판다스(Python Pandas), 시리즈(Series), 데이터프레임(Python Dataframe)

반응형


| 파이선 판다스(Python Pandas)


파이썬 판다스(Python Pandas)는 파이썬 언어로 데이터를 분석하기 위한 쉽게하기 위한 자료구조 및 기능들을 제공하는 패키지입니다. 판다스가 제공하는 여러 기능들을 통해서 데이터 분석 과정 중 가장 까다로운 작업 중 하나인 데이터 전처리를 보다 쉽게할 수 처리할 수 있습니다.



| 파이썬 시리즈(Python Series)


파이썬 시리즈(Python Series)는 판다스의 중요 자료구조 중 하나입니다. 시리즈는 인덱스와 그와 짝지어진 데이터로 이루어져 있습니다. 


   < 출처 : https://www.coursera.org/learn/python-data-analysis >


다음은 시리즈 자료구조를 이용한 예시들입니다. 


import pandas as pd

animals = ['Tigers', 'Bears', 'Moose']
p = pd.Series(animals) # 자동적으로 각 데이터에 인덱스를 부여
print(p)
'''
0 Tigers
1 Bears
2 Moose
dtype: object
'''

numbers = [1,2,3]
nums = pd.Series(numbers);
print(nums)
'''
0 1
1 2
2 3
dtype: int64
'''

animals = ['Tiger', 'Bear', None] # None값을 줘도 그 값이 인덱스에 매핑되서 표현
p = pd.Series(animals)
print(p)
'''
0 Tiger
1 Bear
2 None
dtype: object
'''

import numpy as np
print(np.nan == None) # numpy에는 값이 없는 것을 의미하는 nan값이 있다. 이것은 None과는 다르다.
# False
print(np.nan == np.nan) # nan끼리는 비교할 수 없다.
# False
print(np.isnan(np.nan)) # nan값인지를 확인하려면 isnan 메서드를 사용해야한다.
# True

samsung = {
'SDS' : 'IT',
'Electronic' : 'IT',
'Display' : 'Hardware'
}
s = pd.Series(samsung) # 딕셔너리 구조도 시리즈 자료구조로 변환할 수 있음. 이때 딕셔너리의 키가 인덱스값이 됨.
print(s)
'''
SDS IT
Electronic IT
Display Hardware
dtype: object
'''
print(s.index) # 인덱스값을 엑세스
# Index(['SDS', 'Electronic', 'Display'], dtype='object')

s = pd.Series(['Tiger','Bear','Moose'], index=['India','America','Canada']) # 리스트 자료형을 통한 인덱스 지정
print(s)
'''
India Tiger
America Bear
Canada Moose
dtype: object
'''
m = pd.Series(['SDS', 'Electronic', 'Display'], index=['Software', 'Software+Hardware', 'Hardware'])
print(m)
'''
Software SDS
Software+Hardware Electronic
Hardware Display
dtype: object
'''

sports = {'Archery' : 'Bhutan',
'Golf':'Scotland',
'Sumo':'Japan',
'Taekwondo':'South Korea'}
s = pd.Series(sports, index=['Golf', 'Sumo', 'Hockey']) # 딕셔너리의 key가 하나의 인덱스처럼 동작한다.
print(s) # 그리고 인덱스를 선택해 원하는 데이터를 추출할 수 있다.
'''
Golf Scotland
Sumo Japan
Hockey NaN
dtype: object
'''


| 파이썬 시리즈 질의하기(Python Quering a Series)


파이썬 시리즈에서 다양한 방법으로 데이터에 접근할 수 있고 관련 정보를 질의할 수 있습니다. 다음은 그에 관련된 예제들입니다.

import pandas as pd
sports = {'Archery': 'Bhutan',
'Golf': 'Scotland',
'Sumo': 'Japan',
'Taekwondo': 'South Korea'}
s = pd.Series(sports)
print(s)
'''
Archery Bhutan
Golf Scotland
Sumo Japan
Taekwondo South Korea
dtype: object
'''
game = {
'Battle' :'FPS',
'Overwatch' : 'FPS',
'LOL' : 'AOS',
'Lineage' : 'RPG'
}
m = pd.Series(game)
print(m)
'''
Battle FPS
Overwatch FPS
LOL AOS
Lineage RPG
dtype: object
'''

m.iloc[2] # 인덱스 위치를 통해 엑세스
# RPG
m.loc['LOL'] # 인덱스명을 통해 엑세스, 딕셔너리의 key를 통한 엑세스 방식과 유사
# AOS
m[3] # iloc[3]과 같음
# FPS
m['Overwatch'] # 인덱스명을 통한 엑세스, loc와 같음
# FPS
m.iloc[0]
# FPS

sports = {99: 'Bhutan',
100: 'Scotland',
101: 'Japan',
102: 'South Korea'}
s = pd.Series(sports)
s = pd.Series([100.00, 120.00, 101.00, 3.00]) # 시리즈 데이터 갱신
print(s)
'''
0 100.0
1 120.0
2 101.0
3 3.0
dtype: float64
'''

total = 0
for item in s: # 시리즈 데이터 순회하며 데이터 총합 구하기
total += item
print(total)
# 324.0

from functools import reduce # reduce를 이용하여 데이터 총합 구하기
total = reduce(lambda x,y: x + y, s.values)
print(total)
# 324.0

import numpy as np
total = np.sum(s) # numpy를 통해서 매우 간단하게 시리즈 데이터의 총합을 구할 수 있음
print(total)
# 324.0

import pandas as pd
import numpy as np
s = pd.Series(np.random.randint(0,1000,10000))
print(s.head()) # 시리즈 데이터의 앞 네자리만 보기
a = pd.Series(np.random.randint(0,10000,40))
print(a.head(10)) # 시리즈 데이터의 앞 10자리만 보기

len(s) # 시리즈 데이터 크기
# 10000

import timeit # ipython의 magic function인 %%timeit를 python 인터프리터에서도 사용하는 방법
mycode ='''
def example():
s = pd.Series(np.random.randint(0,1000,10000))
summary=0
for item in s:
summary+=item
'''
print(timeit.timeit(stmt=mycode, number=10000000))
# 0.56461516

s += 2 # numpy의 브로드캐스팅을 통한 연산. 다른 차원의 자료구조도 numpy의 브로드캐스팅
# 을 통하여 쉽게 연산 가능하다. s의 차원은 (1,10000) 이지만 단일 정수를 더해도
# numpy 내부에서 브로드캐스팅이 일어나 2의 차원이 (1, 10000)으로 확장되어 연산이 가능해진다.
# 이에 관한 포스팅은 후에 게시할 예정
print(s.head())
'''
0 274
1 33
2 146
3 200
4 547
dtype: int64
'''
for label, value in s.iteritems(): # 위의 s+=2 연산과 같다. 위 연산에 비해 코드량이 훨씬 더 많고 복잡하다.
s.set_value(label, value+2)
s.head()
print(s.head())
'''
0 274
1 33
2 146
3 200
4 547
dtype: int64
'''
s = pd.Series([1, 2, 3]) # 시리즈 자료구조에 데이터를 추가할 수 있다.
s.loc['Animal'] = 'Bears'
print(s)
'''
0 1
1 2
2 3
Animal Bears
dtype: object
'''
original_sports = pd.Series({'Archery': 'Bhutan',
'Golf': 'Scotland',
'Sumo': 'Japan',
'Taekwondo': 'South Korea'})
cricket_loving_countries = pd.Series(['Australia', # 시리즈 자료구조는 딕셔너리와 다르게 index값의 중복이 허용된다.
'Barbados', # 왜냐하면 인덱스의 숫서로 값을 구분하기 때문이다.
'Pakistan',
'England'],
index=['Cricket',
'Cricket',
'Cricket',
'Cricket'])
all_countries = original_sports.append(cricket_loving_countries)
print(original_sports)
'''
Archery Bhutan
Golf Scotland
Sumo Japan
Taekwondo South Korea
dtype: object
'''
print(cricket_loving_countries)
'''
Cricket Australia
Cricket Barbados
Cricket Pakistan
Cricket England
dtype: object
'''
print(all_countries)
'''
Archery Bhutan
Golf Scotland
Sumo Japan
Taekwondo South Korea
Cricket Australia
Cricket Barbados
Cricket Pakistan
Cricket England
dtype: object
'''
print(all_countries.loc['Cricket'])
'''
Cricket Australia
Cricket Barbados
Cricket Pakistan
Cricket England
dtype: object
'''


| 파이썬 데이터프레임(Python DataFrame)


파이썬 데이터프레임은 판다스에서 제공하는 자료구조로 데이터 분석을 하게 될 때 가장 많이 보게되는 자료구조입니다. 판다스 자료구조의 핵심 중의 핵심이라고 할 수 있죠. 데이터 프레임은 다음과 같은 구조로 되어 있습니다.


< 출처 : https://www.coursera.org/learn/python-data-analysis >


다음은 데이터프레임과 관련된 예제입니다.

import pandas as pd
purchase_1 = pd.Series({'Name': 'Chris', # 시리즈 데이터를 묶어서 데이터프레임 데이터 만들기
'Item Purchased': 'Dog Food',
'Cost': 22.50})
purchase_2 = pd.Series({'Name': 'Kevyn',
'Item Purchased': 'Kitty Litter',
'Cost': 2.50})
purchase_3 = pd.Series({'Name': 'Vinod',
'Item Purchased': 'Bird Seed',
'Cost': 5.00})
purchase_4 = pd.Series({ 'Name' : 'power',
'Item Purchased' : 'Daniel',
'Cost' : 9.42})
df = pd.DataFrame([purchase_1, purchase_2, purchase_3, purchase_4], index=['Store 1', 'Store 1', 'Store 2', 'Store 3'])
h = df.head()
print(h)
'''
Name Item Purchased Cost
Store 1 Chris Dog Food 22.50
Store 1 Kevyn Kitty Litter 2.50
Store 2 Vinod Bird Seed 5.00
Store 3 power Daniel 9.42
'''
print(df.loc['Store 2'])
'''
Cost 5
Item Purchased Bird Seed
Name Vinod
Name: Store 2, dtype: object
'''
type(df.loc['Store 2'])
# pandas.core.series.Series
print(df.loc['Store 1', 'Cost']) # Store 1인 행에 컬럼값이 'Cost'인 요소 구하기
'''
Store 1 22.5
Store 1 2.5
Name: Cost, dtype: float64
'''
T = df.T # Transpose
print(T)
'''
Store 1 Store 1 Store 2 Store 3
Cost 22.5 2.5 5 9.42
Item Purchased Dog Food Kitty Litter Bird Seed Daniel
Name Chris Kevyn Vinod power
'''
print(df.loc[:,['Name', 'Cost']]) # Name과 Cost의 컬럼에 해당되는 모든 행을 출력
'''
Name Cost
Store 1 Chris 22.50
Store 1 Kevyn 2.50
Store 2 Vinod 5.00
Store 3 power 9.42
'''
print(df.loc[['Store 1', 'Store 2'], ['Item Purchased', 'Cost']]) # Store1, Store2 행과 Item Purchased, Cost 열에 해당되는 모든 요소 출력
'''
Item Purchased Cost
Store 1 Dog Food 22.5
Store 1 Kitty Litter 2.5
Store 2 Bird Seed 5.0
'''
drop_df= df.drop('Store 1') # 데이터프레임 중 Store1인 행을 제거한 데이터프레임을 반환 원본 데이터프레임은 변화없음
print(drop_df)
'''
Name Item Purchased Cost
Store 2 Vinod Bird Seed 5.00
Store 3 power Daniel 9.42
'''
print(df)
'''
Name Item Purchased Cost
Store 1 Chris Dog Food 22.50
Store 1 Kevyn Kitty Litter 2.50
Store 2 Vinod Bird Seed 5.00
Store 3 power Daniel 9.42
'''
copy_df = df.copy()
copy_df = copy_df.drop('Store 1') # 위의 연산은 df를 복사하고 난 후 그 복사된 데이터를 드롭한 데이터 프레임을 넘겨주는 것
print(copy_df)
'''
Name Item Purchased Cost
Store 2 Vinod Bird Seed 5.00
Store 3 power Daniel 9.42
'''

del copy_df['Name'] # 컬럼을 삭제하는 방법. 원본 데이터 변화 있음 주의해야 함
print(copy_df)
'''
Item Purchased Cost
Store 2 Bird Seed 5.00
Store 3 Daniel 9.42
'''

df['Location'] = None # 데이터 추가방법, Series를 이용하지 않고도 리스트로 추가 가능하다
df['Sale'] = [True, False, True, True]
print(df)
'''
Name Item Purchased Cost Location Sale
Store 1 Chris Dog Food 22.50 None True
Store 1 Kevyn Kitty Litter 2.50 None False
Store 2 Vinod Bird Seed 5.00 None True
Store 3 power Daniel 9.42 None True
'''

costs = df['Cost'] # 해당 컬럼의 전체 행 추출
print(costs)
'''
Store 1 22.50
Store 1 2.50
Store 2 5.00
Store 3 9.42
Name: Cost, dtype: float64
'''
costs+=2 # 해당 컬럼의 전체행에 2를 더함. 브로드캐스팅 방식으로 연산
print(costs)
'''
Store 1 24.50
Store 1 4.50
Store 2 7.00
Store 3 11.42
Name: Cost, dtype: float64
'''



| 파이썬 데이터프레임 데이터 추출(Python DataFrame Data Access and Extraction)


다음은 예제 csv 파일을 가지고 진행해 보겠습니다. 이 csv 파일은 올림픽의 데이터와 관련된 csv 파일입니다.


olympics.csv


import pandas as pd

df = pd.read_csv('olympics.csv') # csv파일 불러오기, 데이터가 이상하게 불려들여짐
# 컬럼명이 한 칸 아래에 위치, 로우명이 오른쪽으로 한 칸 밀려있음
print(df.head())
'''
0 1 2 ... 13 14 15
0 NaN № Summer 01 ! ... 02 ! 03 ! Combined total
1 Afghanistan (AFG) 13 0 ... 0 2 2
2 Algeria (ALG) 12 5 ... 2 8 15
3 Argentina (ARG) 23 18 ... 24 28 70
4 Armenia (ARM) 5 1 ... 2 9 12
'''

df = pd.read_csv('olympics.csv', index_col=0, skiprows=1) # 잘못 로드된 데이터를 제대로 불려들임
# index_col은 인덱스의 위치를 컬럼의 인덱스로 나타냄
# skiprows는 컬럼명을 맞추기 위해 얼마만큼의 행을 건너뛸지를 나타냄
print(df.head())
'''
№ Summer 01 ! ... 03 !.2 Combined total
Afghanistan (AFG) 13 0 ... 2 2
Algeria (ALG) 12 5 ... 8 15
Argentina (ARG) 23 18 ... 28 70
Armenia (ARM) 5 1 ... 9 12
Australasia (ANZ) [ANZ] 2 3 ... 5 12
'''

for col in df.columns: # 데이터프레임 데이터 전처리, 컬럼명 바꾸기
if col[:2] == '01':
df.rename(columns={col:'Gold' + col[4:]}, inplace=True) # inplace는 새로운 데이터프레임을 복사해서 줄 것인지
if col[:2] == '02': # 기존의 것을 대체할 것인지를 결정함
df.rename(columns={col:'Silver' + col[4:]}, inplace=True)
if col[:2] == '03':
df.rename(columns={col: 'Bronze' + col[4:]}, inplace=True)
if col[:1] == '№':
df.rename(columns={col: '#' + col[1:]}, inplace=True)

print(df.columns)
'''
Index(['# Summer', 'Gold', 'Silver', 'Bronze', 'Total', '# Winter', 'Gold.1',
'Silver.1', 'Bronze.1', 'Total.1', '# Games', 'Gold.2', 'Silver.2',
'Bronze.2', 'Combined total'],
dtype='object')

'''

print(df['Gold'] > 0) # Gold 컬럼에서 0 보다 큰 값인지 여부 확인
'''
Afghanistan (AFG) False
Algeria (ALG) True
Argentina (ARG) True
Armenia (ARM) True
Australasia (ANZ) [ANZ] True
Australia (AUS) [AUS] [Z] True
Austria (AUT) True
Azerbaijan (AZE) True
Bahamas (BAH) True
Bahrain (BRN) False
Barbados (BAR) [BAR] False
Belarus (BLR) True
Belgium (BEL) True
Bermuda (BER) False
Bohemia (BOH) [BOH] [Z] False
Botswana (BOT) False
Brazil (BRA) True
British West Indies (BWI) [BWI] False
Bulgaria (BUL) [H] True
Burundi (BDI) True
Cameroon (CMR) True
Canada (CAN) True
Chile (CHI) [I] True
China (CHN) [CHN] True
Colombia (COL) True
Costa Rica (CRC) True
Ivory Coast (CIV) [CIV] False
Croatia (CRO) True
Cuba (CUB) [Z] True
Cyprus (CYP) False
...
Sri Lanka (SRI) [SRI] False
Sudan (SUD) False
Suriname (SUR) [E] True
Sweden (SWE) [Z] True
Switzerland (SUI) True
Syria (SYR) True
Chinese Taipei (TPE) [TPE] [TPE2] True
Tajikistan (TJK) False
Tanzania (TAN) [TAN] False
Thailand (THA) True
Togo (TOG) False
Tonga (TGA) False
Trinidad and Tobago (TRI) [TRI] True
Tunisia (TUN) True
Turkey (TUR) True
Uganda (UGA) True
Ukraine (UKR) True
United Arab Emirates (UAE) True
United States (USA) [P] [Q] [R] [Z] True
Uruguay (URU) True
Uzbekistan (UZB) True
Venezuela (VEN) True
Vietnam (VIE) False
Virgin Islands (ISV) False
Yugoslavia (YUG) [YUG] True
Independent Olympic Participants (IOP) [IOP] False
Zambia (ZAM) [ZAM] False
Zimbabwe (ZIM) [ZIM] True
Mixed team (ZZX) [ZZX] True
Totals True
Name: Gold, Length: 147, dtype: bool
'''
only_gold = df.where(df['Gold']>5) # Gold 컬럼에서 5보다 큰 행들의 모음을 데이터프레임 형식으로 반환
print(only_gold.head())
'''
# Summer ... Combined total
Afghanistan (AFG) NaN ... NaN
Algeria (ALG) NaN ... NaN
Argentina (ARG) 23.0 ... 70.0
Armenia (ARM) NaN ... NaN
Australasia (ANZ) [ANZ] NaN ... NaN
'''
print(only_gold['Gold'].count()) # Gold 컬럼중에서 NaN이 아닌 수를 구하기
# 62
only_gold = only_gold.dropna() # 데이터 프레임에서 NaN이 포함된 행들 다 drop하기
print(only_gold.head())
'''
# Summer ... Combined total
Argentina (ARG) 23.0 ... 70.0
Australia (AUS) [AUS] [Z] 25.0 ... 480.0
Austria (AUT) 26.0 ... 304.0
Azerbaijan (AZE) 5.0 ... 26.0
Belarus (BLR) 5.0 ... 90.0
'''

only_gold = df[df['Gold'] > 0] # Gold가 0보다 큰 행들을 모아 데이터프레임으로 리턴
# 위의 방식보다 훨씬 간단하다
print(only_gold.head())
'''
# Summer ... Combined total
Algeria (ALG) 12 ... 15
Argentina (ARG) 23 ... 70
Armenia (ARM) 5 ... 12
Australasia (ANZ) [ANZ] 2 ... 12
Australia (AUS) [AUS] [Z] 25 ... 480

'''
gold_and_gold1 = df[(df['Gold'] > 0) & (df['Gold.1'] > 0)] # Gold와 Gold.1값이 동시에 0이 넘는 행들을 선택
print(gold_and_gold1.head())
'''
# Summer ... Combined total
Australia (AUS) [AUS] [Z] 25 ... 480
Austria (AUT) 26 ... 304
Belarus (BLR) 5 ... 90
Belgium (BEL) 25 ... 147
Bulgaria (BUL) [H] 19 ... 220
'''

df['country'] = df.index # 인덱스로 쓰인 데이터를 'country' 컬럼의 데이터로 만들어 쓰기
df = df.set_index('Silver') # Silver라는 새로운 인덱스 만듬
print(df.head())
'''
# Summer ... country
Silver ...
0 13 ... Afghanistan (AFG)
2 12 ... Algeria (ALG)
24 23 ... Argentina (ARG)
2 5 ... Armenia (ARM)
4 2 ... Australasia (ANZ) [ANZ]
'''
df = df.reset_index() # 인덱스 리셋
print(df.head())
'''
Silver ... country
0 0 ... Afghanistan (AFG)
1 2 ... Algeria (ALG)
2 24 ... Argentina (ARG)
3 2 ... Armenia (ARM)
4 4 ... Australasia (ANZ) [ANZ]
'''
df.index = df['Silver']
print(df.head())
'''
Silver ... country
Silver ...
0 0 ... Afghanistan (AFG)
2 2 ... Algeria (ALG)
24 24 ... Argentina (ARG)
2 2 ... Armenia (ARM)
4 4 ... Australasia (ANZ) [ANZ]
'''
df = df.sort_index() # 인덱스 정렬
print(df.head())
'''
Silver ... country
0 0 ... Afghanistan (AFG)
1 2 ... Algeria (ALG)
2 24 ... Argentina (ARG)
3 2 ... Armenia (ARM)
4 4 ... Australasia (ANZ) [ANZ]
'''
# !cat olympics.csv
참고자료 : https://www.coursera.org/learn/python-data-analysis



반응형

이 글을 공유하기

댓글

Designed by JB FACTORY