파이썬 표준 라이브러리와 pandas를 이용하여 데이터를 분석하기 좋게 다듬어보자.
7.1 데이터 합치기
7.2 재형성과 피벗
7.3 데이터 변형
7.4 문자열 다루기
7.5 예제 : 미국 농무부 음식 데이터베이스
7.1.1 데이터베이스 스타일로 DataFrame 합치기
7.1.2 색인 머지하기
7.1.3 축 따라 이어붙이기
7.1.4 겹치는 데이터 합치기
from pandas import DataFrame, Series
import pandas as pd
df1 = DataFrame({'key' : ['b','b','a','c','a','a','b'],
'data1': range(7)})
df2 = DataFrame({'key' : ['a','b','d'],
'data2': range(3)})
df1
data1 | key | |
---|---|---|
0 | 0 | b |
1 | 1 | b |
2 | 2 | a |
3 | 3 | c |
4 | 4 | a |
5 | 5 | a |
6 | 6 | b |
7 rows × 2 columns
df2
data2 | key | |
---|---|---|
0 | 0 | a |
1 | 1 | b |
2 | 2 | d |
3 rows × 2 columns
pd.merge(df1,df2)
data1 | key | data2 | |
---|---|---|---|
0 | 0 | b | 1 |
1 | 1 | b | 1 |
2 | 6 | b | 1 |
3 | 2 | a | 0 |
4 | 4 | a | 0 |
5 | 5 | a | 0 |
6 rows × 3 columns
pd.merge(df1,df2,on='key')
data1 | key | data2 | |
---|---|---|---|
0 | 0 | b | 1 |
1 | 1 | b | 1 |
2 | 6 | b | 1 |
3 | 2 | a | 0 |
4 | 4 | a | 0 |
5 | 5 | a | 0 |
6 rows × 3 columns
df3 = DataFrame({'lkey' : ['b','b','a','c','a','a','b'],
'data1': range(7)})
df4 = DataFrame({'rkey' : ['a','b','d'],
'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey')
data1 | lkey | data2 | rkey | |
---|---|---|---|---|
0 | 0 | b | 1 | b |
1 | 1 | b | 1 | b |
2 | 6 | b | 1 | b |
3 | 2 | a | 0 | a |
4 | 4 | a | 0 | a |
5 | 5 | a | 0 | a |
6 rows × 4 columns
pd.merge(df1, df2, how='outer')
data1 | key | data2 | |
---|---|---|---|
0 | 0 | b | 1 |
1 | 1 | b | 1 |
2 | 6 | b | 1 |
3 | 2 | a | 0 |
4 | 4 | a | 0 |
5 | 5 | a | 0 |
6 | 3 | c | NaN |
7 | NaN | d | 2 |
8 rows × 3 columns
df1 = DataFrame({'key' : ['b','b','a','c','a','b'],
'data1': range(6)})
df2 = DataFrame({'key' : ['a','b','a', 'b', 'd'],
'data2': range(5)})
df1
data1 | key | |
---|---|---|
0 | 0 | b |
1 | 1 | b |
2 | 2 | a |
3 | 3 | c |
4 | 4 | a |
5 | 5 | b |
6 rows × 2 columns
df2
data2 | key | |
---|---|---|
0 | 0 | a |
1 | 1 | b |
2 | 2 | a |
3 | 3 | b |
4 | 4 | d |
5 rows × 2 columns
pd.merge(df1, df2, on='key', how='left')
data1 | key | data2 | |
---|---|---|---|
0 | 0 | b | 1 |
1 | 0 | b | 3 |
2 | 1 | b | 1 |
3 | 1 | b | 3 |
4 | 5 | b | 1 |
5 | 5 | b | 3 |
6 | 2 | a | 0 |
7 | 2 | a | 2 |
8 | 4 | a | 0 |
9 | 4 | a | 2 |
10 | 3 | c | NaN |
11 rows × 3 columns
pd.merge(df1, df2, how='inner')
data1 | key | data2 | |
---|---|---|---|
0 | 0 | b | 1 |
1 | 0 | b | 3 |
2 | 1 | b | 1 |
3 | 1 | b | 3 |
4 | 5 | b | 1 |
5 | 5 | b | 3 |
6 | 2 | a | 0 |
7 | 2 | a | 2 |
8 | 4 | a | 0 |
9 | 4 | a | 2 |
10 rows × 3 columns
left = DataFrame({'key1' : ['foo', 'foo', 'bar'],
'key2' : ['one', 'two', 'one'],
'lval' : [1, 2, 3]})
right = DataFrame({'key1' : ['foo', 'foo', 'bar', 'bar'],
'key2' : ['one', 'one', 'one', 'two'],
'rval' : [4, 5, 6, 7]})
left
key1 | key2 | lval | |
---|---|---|---|
0 | foo | one | 1 |
1 | foo | two | 2 |
2 | bar | one | 3 |
3 rows × 3 columns
right
key1 | key2 | rval | |
---|---|---|---|
0 | foo | one | 4 |
1 | foo | one | 5 |
2 | bar | one | 6 |
3 | bar | two | 7 |
4 rows × 3 columns
pd.merge(left, right, on=['key1', 'key2'], how='outer')
key1 | key2 | lval | rval | |
---|---|---|---|---|
0 | foo | one | 1 | 4 |
1 | foo | one | 1 | 5 |
2 | foo | two | 2 | NaN |
3 | bar | one | 3 | 6 |
4 | bar | two | NaN | 7 |
5 rows × 4 columns
left1 = DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'],
'value': range(6)})
right1 = DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
left1
key | value | |
---|---|---|
0 | a | 0 |
1 | b | 1 |
2 | a | 2 |
3 | a | 3 |
4 | b | 4 |
5 | c | 5 |
6 rows × 2 columns
right1
group_val | |
---|---|
a | 3.5 |
b | 7.0 |
2 rows × 1 columns
pd.merge(left1, right1, left_on='key', right_index=True, how='outer')
pd.merge(left1, right1, left_on='key', right_index=True)
key | value | group_val | |
---|---|---|---|
0 | a | 0 | 3.5 |
2 | a | 2 | 3.5 |
3 | a | 3 | 3.5 |
1 | b | 1 | 7.0 |
4 | b | 4 | 7.0 |
5 rows × 3 columns
lefth = DataFrame({'key1' : ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
'key2' : [2000, 2001, 2002, 2001, 2002],
'data' : np.arange(5.)})
righth = DataFrame(np.arange(12).reshape((6,2)),
index=[['Nebada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'],
[2001, 2000, 2000, 2000, 2001, 2002]],
columns = ['event1', 'event2'])
lefth
data | key1 | key2 | |
---|---|---|---|
0 | 0 | Ohio | 2000 |
1 | 1 | Ohio | 2001 |
2 | 2 | Ohio | 2002 |
3 | 3 | Nevada | 2001 |
4 | 4 | Nevada | 2002 |
5 rows × 3 columns
righth
event1 | event2 | ||
---|---|---|---|
Nebada | 2001 | 0 | 1 |
Nevada | 2000 | 2 | 3 |
Ohio | 2000 | 4 | 5 |
2000 | 6 | 7 | |
2001 | 8 | 9 | |
2002 | 10 | 11 |
6 rows × 2 columns
pd.merge(lefth, righth, left_on=['key1', 'key2'], right_index=True)
data | key1 | key2 | event1 | event2 | |
---|---|---|---|---|---|
0 | 0 | Ohio | 2000 | 4 | 5 |
0 | 0 | Ohio | 2000 | 6 | 7 |
1 | 1 | Ohio | 2001 | 8 | 9 |
2 | 2 | Ohio | 2002 | 10 | 11 |
4 rows × 5 columns
pd.merge(lefth, righth, left_on=['key1', 'key2'], right_index=True, how='outer')
data | key1 | key2 | event1 | event2 | |
---|---|---|---|---|---|
0 | 0 | Ohio | 2000 | 4 | 5 |
0 | 0 | Ohio | 2000 | 6 | 7 |
1 | 1 | Ohio | 2001 | 8 | 9 |
2 | 2 | Ohio | 2002 | 10 | 11 |
3 | 3 | Nevada | 2001 | NaN | NaN |
4 | 4 | Nevada | 2002 | NaN | NaN |
4 | NaN | Nebada | 2001 | 0 | 1 |
4 | NaN | Nevada | 2000 | 2 | 3 |
8 rows × 5 columns
left2 = DataFrame([[1., 2.], [3., 4.], [5., 6.]], index = ['a', 'c', 'e'],
columns=['Ohio', 'Nebada'])
right2 = DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]], index = ['b', 'c', 'd', 'e'],
columns=['Missouri', 'Alabama'])
left2
Ohio | Nebada | |
---|---|---|
a | 1 | 2 |
c | 3 | 4 |
e | 5 | 6 |
3 rows × 2 columns
right2
Missouri | Alabama | |
---|---|---|
b | 7 | 8 |
c | 9 | 10 |
d | 11 | 12 |
e | 13 | 14 |
4 rows × 2 columns
pd.merge(left2, right2, how='outer', left_index=True, right_index=True)
Ohio | Nebada | Missouri | Alabama | |
---|---|---|---|---|
a | 1 | 2 | NaN | NaN |
b | NaN | NaN | 7 | 8 |
c | 3 | 4 | 9 | 10 |
d | NaN | NaN | 11 | 12 |
e | 5 | 6 | 13 | 14 |
5 rows × 4 columns
7.1.3 축 따라 이어붙이기
arr = np.arange(12).reshape((3, 4))
arr
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
np.concatenate([arr, arr], axis=1)
array([[ 0, 1, 2, 3, 0, 1, 2, 3], [ 4, 5, 6, 7, 4, 5, 6, 7], [ 8, 9, 10, 11, 8, 9, 10, 11]])
s1 = Series([0, 1], index=['a', 'b'])
s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = Series([5, 6], index=['f', 'g'])
s1
a 0 b 1 dtype: int64
s2
c 2 d 3 e 4 dtype: int64
s3
f 5 g 6 dtype: int64
pd.concat([s1, s2, s3])
a 0 b 1 c 2 d 3 e 4 f 5 g 6 dtype: int64
pd.concat([s1, s2, s3], axis=1)
0 | 1 | 2 | |
---|---|---|---|
a | 0 | NaN | NaN |
b | 1 | NaN | NaN |
c | NaN | 2 | NaN |
d | NaN | 3 | NaN |
e | NaN | 4 | NaN |
f | NaN | NaN | 5 |
g | NaN | NaN | 6 |
7 rows × 3 columns
s4 = pd.concat([s1*5, s3])
s4
a 0 b 5 f 5 g 6 dtype: int64
pd.concat([s1, s4], axis=1)
0 | 1 | |
---|---|---|
a | 0 | 0 |
b | 1 | 5 |
f | NaN | 5 |
g | NaN | 6 |
4 rows × 2 columns
pd.concat([s1, s4], axis=1, join='inner')
0 | 1 | |
---|---|---|
a | 0 | 0 |
b | 1 | 5 |
2 rows × 2 columns
pd.concat([s1, s4], axis=1, join_axes=[['a', 'c', 'b', 'e']])
0 | 1 | |
---|---|---|
a | 0 | 0 |
c | NaN | NaN |
b | 1 | 5 |
e | NaN | NaN |
4 rows × 2 columns
result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three'])
result
one a 0 b 1 two a 0 b 1 three f 5 g 6 dtype: int64
result.unstack()
a | b | f | g | |
---|---|---|---|---|
one | 0 | 1 | NaN | NaN |
two | 0 | 1 | NaN | NaN |
three | NaN | NaN | 5 | 6 |
3 rows × 4 columns
pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'])
one | two | three | |
---|---|---|---|
a | 0 | NaN | NaN |
b | 1 | NaN | NaN |
c | NaN | 2 | NaN |
d | NaN | 3 | NaN |
e | NaN | 4 | NaN |
f | NaN | NaN | 5 |
g | NaN | NaN | 6 |
7 rows × 3 columns
df1 = DataFrame(np.arange(6).reshape(3, 2), index = ['a', 'b', 'c'],
columns = ['one', 'two'])
df2 = DataFrame(5 + np.arange(4).reshape(2, 2), index = ['a', 'c'],
columns = ['three', 'four'])
pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])
level1 | level2 | |||
---|---|---|---|---|
one | two | three | four | |
a | 0 | 1 | 5 | 6 |
b | 2 | 3 | NaN | NaN |
c | 4 | 5 | 7 | 8 |
3 rows × 4 columns
pd.concat({'level1': df1, 'level2': df2}, axis=1)
level1 | level2 | |||
---|---|---|---|---|
one | two | three | four | |
a | 0 | 1 | 5 | 6 |
b | 2 | 3 | NaN | NaN |
c | 4 | 5 | 7 | 8 |
3 rows × 4 columns
df1 = DataFrame(np.random.randn(3,4), columns=['a', 'b', 'c', 'd'])
df2 = DataFrame(np.random.randn(2,3), columns=[ 'b', 'd', 'a'])
df1
a | b | c | d | |
---|---|---|---|---|
0 | 0.793345 | -1.455478 | 0.125752 | -1.663345 |
1 | -1.067388 | -0.998623 | 0.901886 | 1.515247 |
2 | -1.018375 | -0.192882 | 1.274698 | 0.493192 |
3 rows × 4 columns
df2
b | d | a | |
---|---|---|---|
0 | 0.204529 | -0.116710 | 1.012163 |
1 | 0.713587 | 0.753889 | -1.876528 |
2 rows × 3 columns
pd.concat([df1, df2], ignore_index=True)
a | b | c | d | |
---|---|---|---|---|
0 | 0.793345 | -1.455478 | 0.125752 | -1.663345 |
1 | -1.067388 | -0.998623 | 0.901886 | 1.515247 |
2 | -1.018375 | -0.192882 | 1.274698 | 0.493192 |
3 | 1.012163 | 0.204529 | NaN | -0.116710 |
4 | -1.876528 | 0.713587 | NaN | 0.753889 |
5 rows × 4 columns
7.1.4 겹치는 데이터 합치기 - 데이터를 합칠 때 머지나 이어붙이기로는 불가능한 상황 = 두 데이터셋의 색인이 일부 겹치거나 전체가 겹치는 경우 - 벡터화된 if-else 구문
a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan], index=['f', 'e', 'd', 'c', 'b', 'a'])
b = Series(np.arange(len(a), dtype=np.float64), index=['f', 'e', 'd', 'c', 'b', 'a'])
b[-1] = np.nan
a
f NaN e 2.5 d NaN c 3.5 b 4.5 a NaN dtype: float64
b
f 0 e 1 d 2 c 3 b 4 a NaN dtype: float64
np.where(pd.isnull(a), b, a)
array([ 0. , 2.5, 2. , 3.5, 4.5, nan])
b[:-2]
f 0 e 1 d 2 c 3 dtype: float64
b[:-2].combine_first(a[2:])
a NaN b 4.5 c 3.0 d 2.0 e 1.0 f 0.0 dtype: float64
df1 = DataFrame({'a': [1., np.nan, 5., np.nan],
'b': [np.nan, 2., np.nan, 6.],
'c': range(2, 18, 4)})
df2 = DataFrame({'a': [5., 4., np.nan, 3., 7],
'b': [np.nan, 3., 4., 6., 8.]})
df1
a | b | c | |
---|---|---|---|
0 | 1 | NaN | 2 |
1 | NaN | 2 | 6 |
2 | 5 | NaN | 10 |
3 | NaN | 6 | 14 |
4 rows × 3 columns
df2
a | b | |
---|---|---|
0 | 5 | NaN |
1 | 4 | 3 |
2 | NaN | 4 |
3 | 3 | 6 |
4 | 7 | 8 |
5 rows × 2 columns
df1.combine_first(df2)
a | b | c | |
---|---|---|---|
0 | 1 | NaN | 2 |
1 | 4 | 2 | 6 |
2 | 5 | 4 | 10 |
3 | 3 | 6 | 14 |
4 | 7 | 8 | NaN |
5 rows × 3 columns
7.2.1 계층적 색인으로 재형성하기 - stack : 데이터의 컬럼을 로우로 피벗 또는 회전 - unstack : 로우를 칼럼으로 피벗시킨다
7.2.2 피버팅으로 데이터 나열 방식 바꾸기
data = DataFrame(np.arange(6).reshape((2, 3)),
index=pd.Index(['Ohio', 'Colorado'], name='state'),
columns = pd.Index(['one', 'two', 'three'], name='number'))
data
number | one | two | three |
---|---|---|---|
state | |||
Ohio | 0 | 1 | 2 |
Colorado | 3 | 4 | 5 |
2 rows × 3 columns
result = data.stack()
result
state number Ohio one 0 two 1 three 2 Colorado one 3 two 4 three 5 dtype: int64
result.unstack()
number | one | two | three |
---|---|---|---|
state | |||
Ohio | 0 | 1 | 2 |
Colorado | 3 | 4 | 5 |
2 rows × 3 columns
7.3.1 중복 제거하기
7.3.2 함수나 매핑 이용해 데이터 변형하기
7.3.3 값 치환하기
7.3.4 축 색인 이름 바꾸기
7.3.5 개별화와 양자화
7.3.6 특이값 찾아내고 제외하기
7.3.7 치환과 임의 샘플링
7.3.8 표시자/더미 변수
7.4.1 문자열 객체 메서드
7.4.2 정규표현식
7.4.3 pandas의 벡터화된 문자열 함수
step 1. 데이터 가져오기
step 2. 음식의 이름과 그룹, id 그리고 제조사 추출
step 3. 음식 그룹의 분포 확인
step 4. 영양소 정보 분석
step 5. 시각화
- 음식 그룹과 영양소의 종류별 중간 값 그래프