반응형
#!/usr/bin/env python
# coding: utf-8
# # Pandas III: 데이터 처리
# # 1. 데이터 합치기
# - merge()
# - join()
# - concat()
# ### 1.1 DBMS 스타일로 DataFrame 합치기
# In[ ]:
from pandas import DataFrame, Series
import pandas as pd
import numpy as np
# #### merge() 함수
# In[ ]:
df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1': range(7)})
df2 = pd.DataFrame({'key': ['a', 'b', 'd'],
'data2': range(3)})
# In[ ]:
df1
# In[ ]:
df2
# In[ ]:
#pd.merge(df1, df2)
pd.merge(df1, df2, on='key')
# In[ ]:
df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1': range(7)})
df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'],
'data2': range(3)})
# In[ ]:
pd.merge(df3, df4, left_on='lkey', right_on='rkey')
# #### 1) inner join
# #### 2) outer join
# - left outer join
# - right outer join
# - full outer join
# In[ ]:
pd.merge(df1, df2, how='outer')
# In[ ]:
df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
df2 = pd.DataFrame({'key': ['a', 'b', 'a', 'b', 'd'],
'data2': range(5)})
# In[ ]:
df1
# In[ ]:
df2
# In[ ]:
pd.merge(df1, df2, on='key', how='left')
# #### <참고> 데카르트 곱 ( Cartesian product )
# In[ ]:
pd.merge(df1, df2, how='inner')
# In[ ]:
left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'],
'key2': ['one', 'two', 'one'],
'lval': [1, 2, 3]})
right = pd.DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
'key2': ['one', 'one', 'one', 'two'],
'rval': [4, 5, 6, 7]})
# In[ ]:
# 여러 key 지정
pd.merge(left, right, on=['key1', 'key2'], how='outer')
# In[ ]:
# 중복되는 컬럼 이름 자동 변경
pd.merge(left, right, on='key1')
# In[ ]:
# 중복되는 컬럼 이름 뒤에 붙일 문자열 지정
pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
# #### merge 함수 인자 목록
# 인자 | 설명
# :---|:---
# left | 머지하려는 DataFrame 중 왼쪽에 위치한 DataFrame
# right | 머지하려는 DataFrame 중 오른쪽에 위치한 DataFrame
# how | 조인 방법. 'inner', 'outer', 'left', 'right' 기본 값은 inner
# on | 조인하려는 로우 이름. 반드시 두 DataFrame 객체 모두에 있는 이름이어야 한다.
# left_on | 조인 키로 사용할 left DataFrame 컬럼
# right_on | 조인 키로 사용할 right DataFrame 컬럼
# left_index | 조인 키로 사용할 left DataFrame의 색인 로우 (다중 색인일 경우의 키)
# right_index | 조인 키로 사용할 right DataFrame의 색인 로우 (다중 색인일 경우의 키)
# suffixes | 중복되는 컬럼의 이름 뒤에 붙인 문자열 지정
#
# ### 1.2 색인으로 머지하기
# In[ ]:
left1 = pd.DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'],
'value': range(6)})
right1 = pd.DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
# In[ ]:
left1
# In[ ]:
right1
# In[ ]:
pd.merge(left1, right1, left_on='key', right_index=True)
# In[ ]:
pd.merge(left1, right1, left_on='key', right_index=True, how='outer')
# #### 다중 색인
# In[ ]:
lefth = pd.DataFrame({'key1': ['Ohio', 'Ohio', 'Ohio',
'Nevada', 'Nevada'],
'key2': [2000, 2001, 2002, 2001, 2002],
'data': np.arange(5.)})
righth = pd.DataFrame(np.arange(12).reshape((6, 2)),
index=[['Nevada', 'Nevada', 'Ohio', 'Ohio',
'Ohio', 'Ohio'],
[2001, 2000, 2000, 2000, 2001, 2002]],
columns=['event1', 'event2'])
# In[ ]:
lefth
# In[ ]:
righth
# In[ ]:
pd.merge(lefth, righth, left_on=['key1', 'key2'], right_index=True)
# In[ ]:
pd.merge(lefth, righth, left_on=['key1', 'key2'],
right_index=True, how='outer')
# In[ ]:
left2 = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]],
index=['a', 'c', 'e'],
columns=['Ohio', 'Nevada'])
right2 = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]],
index=['b', 'c', 'd', 'e'],
columns=['Missouri', 'Alabama'])
# In[ ]:
left2
# In[ ]:
right2
# In[ ]:
pd.merge(left2, right2, how='outer', left_index=True, right_index=True)
# #### join() 함수: DataFrame 2개 이상 조인 가능
# In[ ]:
left2.join(right2, how='outer')
# In[ ]:
left1.join(right1, on='key') # Default: how = 'left'
# In[ ]:
another = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]],
index=['a', 'c', 'e', 'f'],
columns=['New York', 'Oregon'])
# In[ ]:
another
# In[ ]:
left2.join([right2, another])
# In[ ]:
left2.join([right2, another], how='outer', sort=False)
# ### 1.3 축 따라 이어붙이기
# #### concat()
# In[ ]:
arr = np.arange(12).reshape((3, 4))
arr
# In[ ]:
s1 = pd.Series([0, 1], index=['a', 'b'])
s2 = pd.Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = pd.Series([5, 6], index=['f', 'g'])
# In[ ]:
pd.concat([s1, s2, s3])
# In[ ]:
pd.concat([s1, s2, s3], axis=1, sort=False)
# In[ ]:
s4 = pd.concat([s1, s3])
s4
# In[ ]:
pd.concat([s1, s4], axis=1, sort=False)
# In[ ]:
# Default: 'outer'
pd.concat([s1, s4], axis=1, join='inner')
# In[ ]:
# 필요한 컬럼 선택
pd.concat([s1, s4], axis=1, join_axes=[['a', 'c', 'b', 'e']])
# #### 인덱스, 컬럼 명 설정 (계층적 색인 생성)
# In[ ]:
result = pd.concat([s1, s2, s3], keys=['one', 'two', 'three'])
result
# In[ ]:
result.unstack()
# In[ ]:
pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'], sort=False)
# #### DataFrame
# In[ ]:
df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],
columns=['one', 'two'])
df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],
columns=['three', 'four'])
# In[ ]:
df1
# In[ ]:
df2
# In[ ]:
pd.concat([df1, df2], axis=1, keys=['level1', 'level2'], sort=False)
# In[ ]:
pd.concat({'level1': df1, 'level2': df2}, axis=1, sort=False)
# In[ ]:
pd.concat([df1, df2], axis=1, keys =['level1', 'level2'],
names=['upper', 'lower'], sort=False)
# #### 인덱스 삭제
# In[ ]:
df1 = pd.DataFrame(np.random.randn(3, 4), columns=['a', 'b', 'c', 'd'])
df2 = pd.DataFrame(np.random.randn(2, 3), columns=['b', 'd', 'a'])
# In[ ]:
df1
# In[ ]:
df2
# In[ ]:
pd.concat([df1, df2], ignore_index=True, sort=False)
# ### 1.4 겹치는 데이터 합치기
# #### combine_first()
# In[ ]:
a = pd.Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan],
index=['f', 'e', 'd', 'c', 'b', 'a'])
b = pd.Series(np.arange(len(a), dtype=np.float64),
index=['f', 'e', 'd', 'c', 'b', 'a'])
b[-1] = np.nan
# In[ ]:
a
# In[ ]:
b
# In[ ]:
np.where(pd.notnull(b), b, a)
#np.where(pd.notnull(a), b, a)
# In[ ]:
b.combine_first(a)
#b[:-2].combine_first(a[2:])
# In[ ]:
df1 = pd.DataFrame({'a': [1., np.nan, 5., np.nan],
'b': [np.nan, 2., np.nan, 6.],
'c': range(2, 18, 4)})
df2 = pd.DataFrame({'a': [5., 4., np.nan, 3., 7.],
'b': [np.nan, 3., 4., 6., 8.]})
# In[ ]:
df1
# In[ ]:
df2
# In[ ]:
df1.combine_first(df2)
# ---
# # 2. 재형성과 피벗
# ### 2.1 계층적 색인으로 재형성하기
# - stack(): 데이터의 컬럼을 로우로 피벗시킨다.
# - unstack(): 로우를 컬럼으로 피벗시킨다.
# In[ ]:
data = pd.DataFrame(np.arange(6).reshape((2, 3)),
index=pd.Index(['Ohio', 'Colorado'], name='state'),
columns=pd.Index(['one', 'two', 'three'],
name='number'))
data
# In[ ]:
result = data.stack()
result
# In[ ]:
result.unstack()
# In[ ]:
result.unstack(0)
result.unstack('state')
# #### 누락된 데이터 처리
# In[ ]:
s1 = pd.Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd'])
s2 = pd.Series([4, 5, 6], index=['c', 'd', 'e'])
data2 = pd.concat([s1, s2], keys=['one', 'two'])
data2
# In[ ]:
data2.unstack()
# In[ ]:
data2.unstack().stack()
# In[ ]:
data2.unstack().stack(dropna=False)
# In[ ]:
df = pd.DataFrame({'left': result, 'right': result + 5},
columns=pd.Index(['left', 'right'], name='side'))
df
# In[ ]:
df.unstack('state')
# In[ ]:
df.unstack('state').stack('side')
# ### 2.2 데이터 나열 형식 변경
# #### Pivoting “Long” to “Wide” Format
# #### pivot()
# In[ ]:
data = pd.read_csv('data/macrodata.csv')
data.head()
# In[ ]:
periods = pd.PeriodIndex(year=data.year, quarter=data.quarter, name='date')
columns = pd.Index(['realgdp', 'infl', 'unemp'], name='item')
data = data.reindex(columns=columns)
data.index = periods.to_timestamp('D', 'end')
# In[ ]:
ldata = data.stack().reset_index().rename(columns={0: 'value'})
ldata.head()
# In[ ]:
pivoted = ldata.pivot('date', 'item', 'value')
pivoted.head()
# In[ ]:
ldata['value2'] = np.random.randn(len(ldata))
ldata.head()
# In[ ]:
pivoted = ldata.pivot('date', 'item')
pivoted.head()
# In[ ]:
pivoted['value'].head()
# #### <비교>
# - pivot()
# - set_index().unstack()
# In[ ]:
unstacked = ldata.set_index(['date', 'item']).unstack('item')
unstacked.head()
# #### Pivoting “Wide” to “Long” Format
# #### melt()
# In[ ]:
df = pd.DataFrame({'key': ['foo', 'bar', 'baz'],
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]})
df
# In[ ]:
melted = pd.melt(df, ['key'])
melted
# In[ ]:
reshaped = melted.pivot('key', 'variable', 'value')
reshaped
# In[ ]:
reshaped.reset_index()
# In[ ]:
pd.melt(df, id_vars=['key'], value_vars=['A', 'B'])
# In[ ]:
pd.melt(df, value_vars=['A', 'B', 'C'])
# In[ ]:
pd.melt(df, value_vars=['key', 'A', 'B'])
# ---
# # 3. 데이터 변형
# ### 3.1 중복 제거하기
# In[ ]:
data = DataFrame({'k1': ['one'] * 3 + ['two'] * 4,
'k2': [1, 1, 2, 3, 3, 4, 4]})
data
# In[ ]:
data.duplicated()
# In[ ]:
data.drop_duplicates()
# In[ ]:
data['v1'] = range(7)
data
# In[ ]:
data.drop_duplicates(['k1'])
# In[ ]:
data.drop_duplicates(['k1', 'k2'], keep='last')
# ### 3.2 함수나 매핑 이용해 데이터 변형하기
# #### map(), apply()
# In[ ]:
data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
'Pastrami', 'corned beef', 'Bacon',
'pastrami', 'honey ham', 'nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
data
# In[ ]:
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
# In[ ]:
lowercased = data['food'].str.lower()
lowercased
# In[ ]:
data['animal'] = lowercased.map(meat_to_animal)
#data['animal'] = lowercased.apply(meat_to_animal)
data
# In[ ]:
data['food'].map(lambda x: meat_to_animal[x.lower()])
#data['food'].apply(lambda x: meat_to_animal[x.lower()])
# ### 3.3 값 치환하기
# #### replace()
# In[ ]:
data = pd.Series([1., -999., 2., -999., -1000., 3.])
data
# In[ ]:
data.replace(-999, np.nan)
# In[ ]:
data.replace([-999, -1000], np.nan)
# In[ ]:
data.replace([-999, -1000], [np.nan, 0])
# In[ ]:
data.replace({-999: np.nan, -1000: 0})
# ### 3.4 축 색인 이름 바꾸기
# In[ ]:
data = pd.DataFrame(np.arange(12).reshape((3, 4)),
index=['Ohio', 'Colorado', 'New York'],
columns=['one', 'two', 'three', 'four'])
data
# In[ ]:
transform = lambda x: x[:4].upper()
data.index.map(transform)
# In[ ]:
data.index = data.index.map(transform)
data
# In[ ]:
data.rename(index=str.title, columns=str.upper)
# In[ ]:
data.rename(index={'OHIO': 'INDIANA'},
columns={'three': 'peekaboo'})
# In[ ]:
data.rename(index={'OHIO': 'INDIANA'}, inplace=True)
data
# ### 3.5 데이터 분류(빈도수 세기)
# - cut()
# - qcut()
# - value_counts()
# In[ ]:
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
# In[ ]:
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins)
cats
# In[ ]:
cats.codes
# In[ ]:
cats.categories
# In[ ]:
# 빈도수 세기
pd.value_counts(cats)
# In[ ]:
# 경계값 포함 여부
pd.cut(ages, [18, 26, 36, 61, 100], right=False)
# In[ ]:
# 그룹 이름 설정
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
pd.cut(ages, bins, labels=group_names)
# In[ ]:
# 4개의 그룹으로 분류: 데이터의 최소값과 최대값을 기준으로 4등분
data = np.random.rand(20)
pd.cut(data, 4, precision=2)
# In[ ]:
data = np.random.randn(1000)
# In[ ]:
# 4개의 그룹으로 분류: 표본 변위치를 기준으로 4등분
cats = pd.qcut(data, 4) # Cut into quartiles
cats
# In[ ]:
pd.value_counts(cats)
# In[ ]:
# 변위치 지정( 0 ~ 1 )
pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.])
# ### 3.6 이상치(Outliers) 제거
# In[ ]:
data = pd.DataFrame(np.random.randn(1000, 4))
data.describe()
# In[ ]:
col = data[2]
col[np.abs(col) > 3]
# In[ ]:
data[(np.abs(data) > 3).any(1)]
#data[(np.abs(data) > 3).any(axis=1)]
# In[ ]:
data[np.abs(data) > 3] = np.sign(data) * 3
data.describe()
# In[ ]:
np.sign(data).head()
# ### 3.7 치환과 임의 샘플링
# In[ ]:
df = pd.DataFrame(np.arange(5 * 4).reshape((5, 4)))
sampler = np.random.permutation(5)
sampler
# In[ ]:
df
# In[ ]:
df.take(sampler)
# In[ ]:
df.sample(n=3)
# In[ ]:
choices = pd.Series([5, 7, -1, 6, 4])
choices
# In[ ]:
draws = choices.sample(n=10, replace=True)
draws
# ### 3.8 더미 변수 ( One-Hot-Encoding )
# In[ ]:
df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
df
# In[ ]:
pd.get_dummies(df['key'])
# In[ ]:
dummies = pd.get_dummies(df['key'], prefix='key')
df_with_dummy = df[['data1']].join(dummies)
df_with_dummy
# In[ ]:
np.random.seed(12345)
values = np.random.rand(10)
values
bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
pd.get_dummies(pd.cut(values, bins))
# ---
# # 4. 문자열 다루기
# ### 4.1 문자열 객체 메서드
# In[ ]:
val = 'a,b, guido'
val.split(',')
# In[ ]:
pieces = [x.strip() for x in val.split(',')]
pieces
# In[ ]:
first, second, third = pieces
first + '::' + second + '::' + third
# In[ ]:
'::'.join(pieces)
# In[ ]:
'guido' in val
# In[ ]:
val.index(',')
# In[ ]:
# 문자열 찾지 못하면 -1 반환
val.find(':')
# In[ ]:
# 문자열 찾지 못하면 예외 발생
val.index(':')
# In[ ]:
val.count(',')
# In[ ]:
val.replace(',', '::')
# In[ ]:
val.replace(',', '')
# ### 4.2 정규표현식
# In[ ]:
import re
# In[ ]:
text = "foo bar\t baz \tqux"
re.split('\s+', text)
# In[ ]:
regex = re.compile('\s+')
regex.split(text)
# In[ ]:
regex.findall(text)
# In[ ]:
text = """Dave dave@google.com
Steve steve@gmail.com
Rob rob@gmail.com
Ryan ryan@yahoo.com
"""
pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
# re.IGNORECASE : 대,소문자 무시
regex = re.compile(pattern, flags=re.IGNORECASE)
# In[ ]:
# findall(): 매칭되는 모든 문자열을 찾아준다.
regex.findall(text)
# In[ ]:
# search(): 첫 번째 매칭되는 문자열(위치)만 찾아준다.
m = regex.search(text)
m
text[m.start():m.end()]
# In[ ]:
# match(): 문자열의 시작부분에서 일치하는 것만 찾아준다.
print(regex.match(text))
# In[ ]:
# sub(): 찾은 패턴을 주어진 문자열로 치환
print(regex.sub('REDACTED', text))
# In[ ]:
# 각 패턴을 그룹으로 설정
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern, flags=re.IGNORECASE)
# In[ ]:
m = regex.match('wesm@bright.net')
m.groups()
# In[ ]:
# findall(): 그룹이 존재하면 튜플로 반환
regex.findall(text)
# In[ ]:
# sub(): 각 패턴의 그룹에 접근( 기호: \1, \2 )
print(regex.sub(r'Username: \1, Domain: \2, Suffix: \3', text))
# ### 4.3 pandas의 벡터화된 문자열
# #### Series의 각 요소에 순차적으로 적용
# In[ ]:
data = {'1': 'a,b,c,d', '2': 'a b c d',
'3': ' a_b_c_d '}
sr = pd.Series(data)
sr
# In[ ]:
# 문자열을 담고 있는지 검사
sr.str.contains('a')
# In[ ]:
sr.str[:5]
# In[ ]:
sr.str.split(',')
# In[ ]:
sr.str.strip()
# In[ ]:
sr.str.replace('a', 'kk')
# In[ ]:
sr.str.len()
# In[ ]:
#sr.str.lower()
sr.str.upper()
# In[ ]:
sr.str.join('=')
# #### pandas 문자열의 정규표현식
# In[ ]:
data1 = {'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com',
'Rob': 'rob@gmail.com', 'Wes': np.nan}
sr1 = pd.Series(data1)
sr1
# In[ ]:
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
# In[ ]:
sr1.str.findall(pattern, flags=re.IGNORECASE)
# ---
# In[ ]:
# end of file
# In[ ]:
반응형
LIST
'Programming' 카테고리의 다른 글
[Python][Library] 2. Pandas - 5. 시계열 (0) | 2022.01.02 |
---|---|
[Python][Library] 2 Pandas - 4. 그룹 연산 (0) | 2022.01.02 |
[Python][Library] 2 Pandas - 2. 파일 입출력 (0) | 2022.01.02 |
[Python][Library] 2 Pandas - 1. 자료구조 (0) | 2022.01.02 |
[Python][Library] 1 Numpy - tutorial (0) | 2022.01.02 |