작성자: admin 작성일시: 2016-07-11 21:34:00 조회수: 2417 다운로드: 117
카테고리: Python 태그목록:

Pandas 데이터 합성

Pandas는 두 개 이상의 데이터프레임을 하나로 합치는 데이터 합성을 지원한다.

Merge

merge 명령은 두 데이터 프레임의 공통 열 혹은 인덱스를 기준으로 데이터베이스 테이블 조인(join)과 같이 두 개의 테이블을 합친다. 기준이 되는 데이터를 키(key)라고 한다.

merge 예제 1

In:
df1 = pd.DataFrame({
    '고객번호': [1001, 1002, 1003, 1004, 1005, 1006, 1007],
    '이름': ['둘리', '도우너', '또치', '길동', '희동', '마이콜', '영희']
    }, columns=['고객번호', '이름']
)
df1
Out:
고객번호 이름
0 1001 둘리
1 1002 도우너
2 1003 또치
3 1004 길동
4 1005 희동
5 1006 마이콜
6 1007 영희
In:
df2 = pd.DataFrame({
    '고객번호': [1001, 1001, 1005, 1006, 1008, 1001],
    '금액': [10000, 20000, 15000, 5000, 100000, 30000]
    }, columns=['고객번호', '금액']
)
df2
Out:
고객번호 금액
0 1001 10000
1 1001 20000
2 1005 15000
3 1006 5000
4 1008 100000
5 1001 30000

merge 명령으로 두 데이터프레임 df1, df2 를 합치면 공통 열인 고객번호 열을 기준으로 데이터를 찾아서 합친다. 이 때 기본적으로는 양쪽 데이터프레임에 모두 키가 존재하는 데이터만 보여주는 inner join 방식을 사용한다.

In:
pd.merge(df1, df2)
Out:
고객번호 이름 금액
0 1001 둘리 10000
1 1001 둘리 20000
2 1001 둘리 30000
3 1005 희동 15000
4 1006 마이콜 5000

outer join 방식은 키 값이 한쪽에만 있어도 양쪽 데이터를 모두 보여준다.

In:
pd.merge(df1, df2, how='outer')
Out:
고객번호 이름 금액
0 1001 둘리 10000.0
1 1001 둘리 20000.0
2 1001 둘리 30000.0
3 1002 도우너 NaN
4 1003 또치 NaN
5 1004 길동 NaN
6 1005 희동 15000.0
7 1006 마이콜 5000.0
8 1007 영희 NaN
9 1008 NaN 100000.0

left, right 방식은 첫번째, 혹은 두번째 데이터프레임을 모두 보여준다.

In:
pd.merge(df1, df2, how='left')
Out:
고객번호 이름 금액
0 1001 둘리 10000.0
1 1001 둘리 20000.0
2 1001 둘리 30000.0
3 1002 도우너 NaN
4 1003 또치 NaN
5 1004 길동 NaN
6 1005 희동 15000.0
7 1006 마이콜 5000.0
8 1007 영희 NaN
In:
pd.merge(df1, df2, how='right')
Out:
고객번호 이름 금액
0 1001 둘리 10000
1 1001 둘리 20000
2 1001 둘리 30000
3 1005 희동 15000
4 1006 마이콜 5000
5 1008 NaN 100000

merge 예제 2

만약 테이블에 키 값이 같은 데이터가 여러개 있는 경우에는 경우의 수를 따져서 조합을 만들어 낸다.

In:
df1 = pd.DataFrame({'key': ['setosa', 'setosa', 'virginica', 'versicolor'], 
                    'petal length': [1.4, 1.3, 1.5, 1.3]})
df1
Out:
key petal length
0 setosa 1.4
1 setosa 1.3
2 virginica 1.5
3 versicolor 1.3
In:
df2 = pd.DataFrame({'key': ['setosa', 'virginica', 'virginica', 'versicolor'], 
                    'petal width': [0.4, 0.3, 0.5, 0.3]})
df2
Out:
key petal width
0 setosa 0.4
1 virginica 0.3
2 virginica 0.5
3 versicolor 0.3
In:
pd.merge(df1, df2)
Out:
key petal length petal width
0 setosa 1.4 0.4
1 setosa 1.3 0.4
2 virginica 1.5 0.3
3 virginica 1.5 0.5
4 versicolor 1.3 0.3

merge 예제 3

In:
df1 = pd.DataFrame({'성별': ['남자', '남자', '여자'], 
                    '연령': ['미성년자', '성인', '미성년자'], 
                    '매출1': [1, 2, 3]})
df1
Out:
매출1 성별 연령
0 1 남자 미성년자
1 2 남자 성인
2 3 여자 미성년자
In:
df2 = pd.DataFrame({'성별': ['남자', '남자', '여자', '여자'],
                    '연령': ['미성년자', '미성년자', '미성년자', '성인'],
                    '매출2': [4, 5, 6, 7]})
df2
Out:
매출2 성별 연령
0 4 남자 미성년자
1 5 남자 미성년자
2 6 여자 미성년자
3 7 여자 성인

이름이 같은 열이 여러개 있는 경우에는 모두 기준 열로 사용된다.

In:
pd.merge(df1, df2, how='outer')
Out:
매출1 성별 연령 매출2
0 1.0 남자 미성년자 4.0
1 1.0 남자 미성년자 5.0
2 2.0 남자 성인 NaN
3 3.0 여자 미성년자 6.0
4 NaN 여자 성인 7.0

기준 열은 on 인수로도 명시적 설정이 가능하다.

In:
pd.merge(df1, df2, on=['성별', '연령'], how='outer')
Out:
매출1 성별 연령 매출2
0 1.0 남자 미성년자 4.0
1 1.0 남자 미성년자 5.0
2 2.0 남자 성인 NaN
3 3.0 여자 미성년자 6.0
4 NaN 여자 성인 7.0

이 때 기준 열이 아니면서 이름이 같은 열에는 _x 또는 _y 와 같은 접미사가 붙는다.

In:
pd.merge(df1, df2, on='성별')
Out:
성별 연령_x 점수1 연령_y 점수2
0 남자 미성년자 1 미성년자 4
1 남자 미성년자 1 미성년자 5
2 남자 성인 2 미성년자 4
3 남자 성인 2 미성년자 5
4 여자 미성년자 3 미성년자 6
5 여자 미성년자 3 성인 7

merge 예제 4

기준 열을 각각의 데이터프레임에 대해 다르게 정하려면 left_on, right_on 인수를 사용한다.

In:
df1 = pd.DataFrame({'key1': ['foo', 'foo', 'bar'], 
                    'key2': ['one', 'two', 'one'], 
                    'lval': [1, 2, 3]})
df1
Out:
key1 key2 lval
0 foo one 1
1 foo two 2
2 bar one 3
In:
df2 = pd.DataFrame({'k1': ['foo', 'foo', 'bar', 'bar'],
                    'k2': ['one', 'one', 'one', 'two'],
                    'rval': [4, 5, 6, 7]})
df2
Out:
k1 k2 rval
0 foo one 4
1 foo one 5
2 bar one 6
3 bar two 7
In:
pd.merge(df1, df2, left_on='key1', right_on="k1")
Out:
key1 key2 lval k1 k2 rval
0 foo one 1 foo one 4
1 foo one 1 foo one 5
2 foo two 2 foo one 4
3 foo two 2 foo one 5
4 bar one 3 bar one 6
5 bar one 3 bar two 7

merge 예제 5

일반 데이터 열이 아닌 인덱스를 기준열로 사용하려면 left_index 또는 right_index 인수를 True 로 설정한다.

In:
df1 = pd.DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'], 'value': range(6)})
df1
Out:
key value
0 a 0
1 b 1
2 a 2
3 a 3
4 b 4
5 c 5
In:
df2 = pd.DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
df2
Out:
group_val
a 3.5
b 7.0
In:
pd.merge(df1, df2, left_on='key', right_index=True)
Out:
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

merge 예제 6

In:
df1 = pd.DataFrame({'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
                    'key2': [2000, 2001, 2002, 2001, 2002],
                    'data': np.arange(5.)})
df1
Out:
data key1 key2
0 0.0 Ohio 2000
1 1.0 Ohio 2001
2 2.0 Ohio 2002
3 3.0 Nevada 2001
4 4.0 Nevada 2002
In:
df2 = pd.DataFrame(np.arange(12).reshape((6, 2)),
                   index=[['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'],
                          [2001, 2000, 2000, 2000, 2001, 2002]],
                   columns=['event1', 'event2'])
df2
Out:
event1 event2
Nevada 2001 0 1
2000 2 3
Ohio 2000 4 5
2000 6 7
2001 8 9
2002 10 11
In:
pd.merge(df1, df2, left_on=['key1', 'key2'], right_index=True)
Out:
data key1 key2 event1 event2
0 0.0 Ohio 2000 4 5
0 0.0 Ohio 2000 6 7
1 1.0 Ohio 2001 8 9
2 2.0 Ohio 2002 10 11
3 3.0 Nevada 2001 0 1

merge 예제 7

In:
df1 = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]], 
                   index=['a', 'c', 'e'], 
                   columns=['Ohio', 'Nevada'])
df1
Out:
Ohio Nevada
a 1.0 2.0
c 3.0 4.0
e 5.0 6.0
In:
df2 = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]], 
                   index=['b', 'c', 'd', 'e'], 
                   columns=['Missouri', 'Alabama'])
df2
Out:
Missouri Alabama
b 7.0 8.0
c 9.0 10.0
d 11.0 12.0
e 13.0 14.0
In:
pd.merge(df1, df2, how='outer', left_index=True, right_index=True)
Out:
Ohio Nevada Missouri Alabama
a 1.0 2.0 NaN NaN
b NaN NaN 7.0 8.0
c 3.0 4.0 9.0 10.0
d NaN NaN 11.0 12.0
e 5.0 6.0 13.0 14.0

join 메서드

merge 명령어 대신 join 메서드를 사용할 수도 있다.

In:
df1.join(df2, how='outer')
Out:
Ohio Nevada Missouri Alabama
a 1.0 2.0 NaN NaN
b NaN NaN 7.0 8.0
c 3.0 4.0 9.0 10.0
d NaN NaN 11.0 12.0
e 5.0 6.0 13.0 14.0

연습 문제 1

두 개의 데이터프레임을 만들고 merge 명령으로 합친다. 단 데이터프레임은 다음 조건을 만족해야 한다.

  1. 각각 5 x 5 이상의 크기를 가진다.
  2. 공통 열을 하나 이상 가진다. 다만 공통 열의 이름은 서로 다르다.

Concat

concat 명령을 사용하면 기준 열(key column)을 사용하지 않고 단순히 데이터를 추가한다.

기본적으로는 아래에 데이터 행을 덧붙이지만 (인덱스가 중복됨) axis=1로 인수를 설정하면 인덱스 기준으로 옆으로 데이터 열를 덧붙인다.

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:
s1
Out:
a    0
b    1
dtype: int64
In:
s2
Out:
c    2
d    3
e    4
dtype: int64
In:
s3
Out:
f    5
g    6
dtype: int64
In:
pd.concat([s1, s2, s3])
Out:
a    0
b    1
c    2
d    3
e    4
f    5
g    6
dtype: int64
In:
pd.concat([s1, s2, s3])
Out:
a    0
b    1
c    2
d    3
e    4
f    5
g    6
dtype: int64
In:
pd.concat([s1, s2, s3], axis=1)
Out:
0 1 2
a 0.0 NaN NaN
b 1.0 NaN NaN
c NaN 2.0 NaN
d NaN 3.0 NaN
e NaN 4.0 NaN
f NaN NaN 5.0
g NaN NaN 6.0
In:
df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'], columns=['one', 'two'])
df1
Out:
one two
a 0 1
b 2 3
c 4 5
In:
df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'], columns=['three', 'four'])
df2
Out:
three four
a 5 6
c 7 8
In:
pd.concat([df1, df2])
Out:
four one three two
a NaN 0.0 NaN 1.0
b NaN 2.0 NaN 3.0
c NaN 4.0 NaN 5.0
a 6.0 NaN 5.0 NaN
c 8.0 NaN 7.0 NaN
In:
pd.concat([df1, df2], axis=1)
Out:
one two three four
a 0 1 5.0 6.0
b 2 3 NaN NaN
c 4 5 7.0 8.0

연습 문제 2

어느 회사의 전반기(1월 ~ 6월) 실적을 나타내는 데이터프레임과 후반기(7월 ~ 12월) 실적을 나타내는 데이터프레임을 만든 뒤 합친다. 실적 정보는 "매출", "비용", "이익" 으로 이루어진다. (이익 = 매출 - 비용).

또한 1년간의 총 실적을 마지막 행으로 덧붙인다.

질문/덧글

아직 질문이나 덧글이 없습니다. 첫번째 글을 남겨주세요!