18. 판다스 10분 완성 2부#
필수 라이브러리
import numpy as np
import pandas as pd
18.1. 합병과 결합: merge-join-concat#
참고: Merging section
18.1.1. 종/횡 결합: pd.concat()
함수#
pd.concat()
함수는 여러 개의 데이터프레임을 하나로 합친다.
axis=0
: 종 결합. 즉 데이터프레임 여러 개의 위아래 결합.
df1 = pd.DataFrame(
{
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
},
index=[0, 1, 2, 3],
)
df1
A | B | C | D | |
---|---|---|---|---|
0 | A0 | B0 | C0 | D0 |
1 | A1 | B1 | C1 | D1 |
2 | A2 | B2 | C2 | D2 |
3 | A3 | B3 | C3 | D3 |
df2 = pd.DataFrame(
{
"A": ["A4", "A5", "A6", "A7"],
"B": ["B4", "B5", "B6", "B7"],
"C": ["C4", "C5", "C6", "C7"],
"D": ["D4", "D5", "D6", "D7"],
},
index=[4, 5, 6, 7],
)
df2
A | B | C | D | |
---|---|---|---|---|
4 | A4 | B4 | C4 | D4 |
5 | A5 | B5 | C5 | D5 |
6 | A6 | B6 | C6 | D6 |
7 | A7 | B7 | C7 | D7 |
df3 = pd.DataFrame(
{
"A": ["A8", "A9", "A10", "A11"],
"B": ["B8", "B9", "B10", "B11"],
"C": ["C8", "C9", "C10", "C11"],
"D": ["D8", "D9", "D10", "D11"],
},
index=[8, 9, 10, 11],
)
df3
A | B | C | D | |
---|---|---|---|---|
8 | A8 | B8 | C8 | D8 |
9 | A9 | B9 | C9 | D9 |
10 | A10 | B10 | C10 | D10 |
11 | A11 | B11 | C11 | D11 |
pd.concat([df1, df2, df3]) # axis=0 이 기본값
A | B | C | D | |
---|---|---|---|---|
0 | A0 | B0 | C0 | D0 |
1 | A1 | B1 | C1 | D1 |
2 | A2 | B2 | C2 | D2 |
3 | A3 | B3 | C3 | D3 |
4 | A4 | B4 | C4 | D4 |
5 | A5 | B5 | C5 | D5 |
6 | A6 | B6 | C6 | D6 |
7 | A7 | B7 | C7 | D7 |
8 | A8 | B8 | C8 | D8 |
9 | A9 | B9 | C9 | D9 |
10 | A10 | B10 | C10 | D10 |
11 | A11 | B11 | C11 | D11 |
axis=1
: 횡 결합. 즉 데이터프레임 여러 개의 좌우 결합.
df4 = pd.DataFrame(
{
"B": ["B2", "B3", "B6", "B7"],
"D": ["D2", "D3", "D6", "D7"],
"F": ["F2", "F3", "F6", "F7"],
},
index=[2, 3, 6, 7],
)
df4
B | D | F | |
---|---|---|---|
2 | B2 | D2 | F2 |
3 | B3 | D3 | F3 |
6 | B6 | D6 | F6 |
7 | B7 | D7 | F7 |
pd.concat([df1, df4], axis=1)
A | B | C | D | B | D | F | |
---|---|---|---|---|---|---|---|
0 | A0 | B0 | C0 | D0 | NaN | NaN | NaN |
1 | A1 | B1 | C1 | D1 | NaN | NaN | NaN |
2 | A2 | B2 | C2 | D2 | B2 | D2 | F2 |
3 | A3 | B3 | C3 | D3 | B3 | D3 | F3 |
6 | NaN | NaN | NaN | NaN | B6 | D6 | F6 |
7 | NaN | NaN | NaN | NaN | B7 | D7 | F7 |
인덱스를 기존의 데이터프레임과 통일시키기 위해 리인덱싱을 활용할 수도 있다.
df1.index
Int64Index([0, 1, 2, 3], dtype='int64')
pd.concat([df1, df4], axis=1).reindex(df1.index)
A | B | C | D | B | D | F | |
---|---|---|---|---|---|---|---|
0 | A0 | B0 | C0 | D0 | NaN | NaN | NaN |
1 | A1 | B1 | C1 | D1 | NaN | NaN | NaN |
2 | A2 | B2 | C2 | D2 | B2 | D2 | F2 |
3 | A3 | B3 | C3 | D3 | B3 | D3 | F3 |
pd.concat([df1, df4.reindex(df1.index)], axis=1)
A | B | C | D | B | D | F | |
---|---|---|---|---|---|---|---|
0 | A0 | B0 | C0 | D0 | NaN | NaN | NaN |
1 | A1 | B1 | C1 | D1 | NaN | NaN | NaN |
2 | A2 | B2 | C2 | D2 | B2 | D2 | F2 |
3 | A3 | B3 | C3 | D3 | B3 | D3 | F3 |
18.1.2. 합병: pd.merge()
함수#
pd.merge()
함수 는 SQL 방식으로 특정 열을 기준으로 두 개의 데이터프레임을 합친다.
다양한 옵션을 지원하는 매우 강력한 도구이다.
예제
실습을 위해 아래 두 데이터프레임을 이용한다.
left = pd.DataFrame({"key": ["foo", "foo"], "lval": [1, 2]})
right = pd.DataFrame({"key": ["foo", "foo"], "rval": [4, 5]})
left
key | lval | |
---|---|---|
0 | foo | 1 |
1 | foo | 2 |
right
key | rval | |
---|---|---|
0 | foo | 4 |
1 | foo | 5 |
on="key"
키워드 인자key
열에 사용된 항목 각각에 대해 다른 열에서 해당 항목과 연관된 값들을 조합할 수 있는 모든 경우의 수를 다룬다.foo
값에 대해lval
열에서 2개의 값이,rval
열에서 2개의 값이 있기에foo
와 관련해서 총 4개의 경우가 생성된다.
key
left.lval
right.rval
경우의 수
foo
1, 2
4, 5
4
pd.merge(left, right, on="key")
key | lval | rval | |
---|---|---|---|
0 | foo | 1 | 4 |
1 | foo | 1 | 5 |
2 | foo | 2 | 4 |
3 | foo | 2 | 5 |
예제
left = pd.DataFrame({"key": ["foo", "bar"], "lval": [1, 2]})
right = pd.DataFrame({"key": ["foo", "bar"], "rval": [4, 5]})
left
key | lval | |
---|---|---|
0 | foo | 1 |
1 | bar | 2 |
right
key | rval | |
---|---|---|
0 | foo | 4 |
1 | bar | 5 |
on="key"
키워드 인자key
열에 사용된 항목별로 모든 경우의 수를 다룬다.foo
값에 대해lval
열에서 1개의 값이,rval
열에서 1개의 값이 있기에foo
와 관련해서 총 1개의 경우가 생성된다.bar
값에 대해lval
열에서 1개의 값이,rval
열에서 1개의 값이 있기에foo
와 관련해서 총 1개의 경우가 생성된다.
key
left.lval
right.rval
경우의 수
foo
1
4
1
bar
2
5
1
pd.merge(left, right, on="key")
key | lval | rval | |
---|---|---|---|
0 | foo | 1 | 4 |
1 | bar | 2 | 5 |
예제
경우의 수는 지정된 열의 항목이 사용된 횟수를 기준으로 한다.
left = pd.DataFrame(
{
"key": ["K0", "K1", "K2", "K3"],
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
}
)
left
key | A | B | |
---|---|---|---|
0 | K0 | A0 | B0 |
1 | K1 | A1 | B1 |
2 | K2 | A2 | B2 |
3 | K3 | A3 | B3 |
right = pd.DataFrame(
{
"key": ["K0", "K1", "K2", "K3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
}
)
right
key | C | D | |
---|---|---|---|
0 | K0 | C0 | D0 |
1 | K1 | C1 | D1 |
2 | K2 | C2 | D2 |
3 | K3 | C3 | D3 |
|
( |
( |
경우의 수 |
---|---|---|---|
|
( |
( |
1 |
|
( |
( |
1 |
|
( |
( |
1 |
|
( |
( |
1 |
result = pd.merge(left, right, on="key")
result
key | A | B | C | D | |
---|---|---|---|---|---|
0 | K0 | A0 | B0 | C0 | D0 |
1 | K1 | A1 | B1 | C1 | D1 |
2 | K2 | A2 | B2 | C2 | D2 |
3 | K3 | A3 | B3 | C3 | D3 |
다양한 키 활용
두 개 이상의 키를 하나의 쌍으로 된 키를 사용하는 경우와 유사함.
left = pd.DataFrame(
{
"key1": ["K0", "K0", "K1", "K2"],
"key2": ["K0", "K1", "K0", "K1"],
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
}
)
left
key1 | key2 | A | B | |
---|---|---|---|---|
0 | K0 | K0 | A0 | B0 |
1 | K0 | K1 | A1 | B1 |
2 | K1 | K0 | A2 | B2 |
3 | K2 | K1 | A3 | B3 |
right = pd.DataFrame(
{
"key1": ["K0", "K1", "K1", "K2"],
"key2": ["K0", "K0", "K0", "K0"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"],
}
)
right
key1 | key2 | C | D | |
---|---|---|---|---|
0 | K0 | K0 | C0 | D0 |
1 | K1 | K0 | C1 | D1 |
2 | K1 | K0 | C2 | D2 |
3 | K2 | K0 | C3 | D3 |
how='inner'
: 지정된 키의 교집합 대상
result = pd.merge(left, right, on=["key1", "key2"]) # how='inner' 가 기본값
result
key1 | key2 | A | B | C | D | |
---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | C0 | D0 |
1 | K1 | K0 | A2 | B2 | C1 | D1 |
2 | K1 | K0 | A2 | B2 | C2 | D2 |
result = pd.merge(left, right, how="inner", on=["key1", "key2"])
result
key1 | key2 | A | B | C | D | |
---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | C0 | D0 |
1 | K1 | K0 | A2 | B2 | C1 | D1 |
2 | K1 | K0 | A2 | B2 | C2 | D2 |
how='outer'
: 지정된 키의 합집합 대상
result = pd.merge(left, right, how="outer", on=["key1", "key2"])
result
key1 | key2 | A | B | C | D | |
---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | C0 | D0 |
1 | K0 | K1 | A1 | B1 | NaN | NaN |
2 | K1 | K0 | A2 | B2 | C1 | D1 |
3 | K1 | K0 | A2 | B2 | C2 | D2 |
4 | K2 | K1 | A3 | B3 | NaN | NaN |
5 | K2 | K0 | NaN | NaN | C3 | D3 |
how='left'
: 왼쪽 데이터프레임의 키에 포함된 항목만 대상
left
key1 | key2 | A | B | |
---|---|---|---|---|
0 | K0 | K0 | A0 | B0 |
1 | K0 | K1 | A1 | B1 |
2 | K1 | K0 | A2 | B2 |
3 | K2 | K1 | A3 | B3 |
result = pd.merge(left, right, how="left", on=["key1", "key2"])
result
key1 | key2 | A | B | C | D | |
---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | C0 | D0 |
1 | K0 | K1 | A1 | B1 | NaN | NaN |
2 | K1 | K0 | A2 | B2 | C1 | D1 |
3 | K1 | K0 | A2 | B2 | C2 | D2 |
4 | K2 | K1 | A3 | B3 | NaN | NaN |
how='right'
: 오른쪽 데이터프레임의 키에 포함된 항목만 대상
right
key1 | key2 | C | D | |
---|---|---|---|---|
0 | K0 | K0 | C0 | D0 |
1 | K1 | K0 | C1 | D1 |
2 | K1 | K0 | C2 | D2 |
3 | K2 | K0 | C3 | D3 |
result = pd.merge(left, right, how="right", on=["key1", "key2"])
result
key1 | key2 | A | B | C | D | |
---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | C0 | D0 |
1 | K1 | K0 | A2 | B2 | C1 | D1 |
2 | K1 | K0 | A2 | B2 | C2 | D2 |
3 | K2 | K0 | NaN | NaN | C3 | D3 |
how='cross'
: 모든 경우의 수 조합
result = pd.merge(left, right, how="cross")
result
key1_x | key2_x | A | B | key1_y | key2_y | C | D | |
---|---|---|---|---|---|---|---|---|
0 | K0 | K0 | A0 | B0 | K0 | K0 | C0 | D0 |
1 | K0 | K0 | A0 | B0 | K1 | K0 | C1 | D1 |
2 | K0 | K0 | A0 | B0 | K1 | K0 | C2 | D2 |
3 | K0 | K0 | A0 | B0 | K2 | K0 | C3 | D3 |
4 | K0 | K1 | A1 | B1 | K0 | K0 | C0 | D0 |
5 | K0 | K1 | A1 | B1 | K1 | K0 | C1 | D1 |
6 | K0 | K1 | A1 | B1 | K1 | K0 | C2 | D2 |
7 | K0 | K1 | A1 | B1 | K2 | K0 | C3 | D3 |
8 | K1 | K0 | A2 | B2 | K0 | K0 | C0 | D0 |
9 | K1 | K0 | A2 | B2 | K1 | K0 | C1 | D1 |
10 | K1 | K0 | A2 | B2 | K1 | K0 | C2 | D2 |
11 | K1 | K0 | A2 | B2 | K2 | K0 | C3 | D3 |
12 | K2 | K1 | A3 | B3 | K0 | K0 | C0 | D0 |
13 | K2 | K1 | A3 | B3 | K1 | K0 | C1 | D1 |
14 | K2 | K1 | A3 | B3 | K1 | K0 | C2 | D2 |
15 | K2 | K1 | A3 | B3 | K2 | K0 | C3 | D3 |
18.1.3. 합병: DataFrame.join()
메서드#
인덱스를 기준으로 두 개의 데이터프레임을 합병할 때 사용한다.
left = pd.DataFrame(
{"A": ["A0", "A1", "A2"], "B": ["B0", "B1", "B2"]}, index=["K0", "K1", "K2"]
)
left
A | B | |
---|---|---|
K0 | A0 | B0 |
K1 | A1 | B1 |
K2 | A2 | B2 |
right = pd.DataFrame(
{"C": ["C0", "C2", "C3"], "D": ["D0", "D2", "D3"]}, index=["K0", "K2", "K3"]
)
right
C | D | |
---|---|---|
K0 | C0 | D0 |
K2 | C2 | D2 |
K3 | C3 | D3 |
left.join(right)
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K1 | A1 | B1 | NaN | NaN |
K2 | A2 | B2 | C2 | D2 |
아래와 같이 pd.merge()
함수를 이용한 결과와 동일하다.
pd.merge(left, right, left_index=True, right_index=True, how='left')
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K1 | A1 | B1 | NaN | NaN |
K2 | A2 | B2 | C2 | D2 |
pd.merge()
함수의 키워드 인자를 동일하게 사용할 수 있다.
how='outer'
left.join(right, how="outer")
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K1 | A1 | B1 | NaN | NaN |
K2 | A2 | B2 | C2 | D2 |
K3 | NaN | NaN | C3 | D3 |
아래 코드가 동일한 결과를 낸다.
pd.merge(left, right, left_index=True, right_index=True, how='outer')
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K1 | A1 | B1 | NaN | NaN |
K2 | A2 | B2 | C2 | D2 |
K3 | NaN | NaN | C3 | D3 |
how='inner'
left.join(right, how="inner")
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K2 | A2 | B2 | C2 | D2 |
아래 코드가 동일한 결과를 낸다.
pd.merge(left, right, left_index=True, right_index=True, how='inner')
A | B | C | D | |
---|---|---|---|---|
K0 | A0 | B0 | C0 | D0 |
K2 | A2 | B2 | C2 | D2 |
18.2. 다중 인덱스MultiIndex#
다중 인덱스를 이용하여 데이터를 보다 체계적으로 다를 수 있다. 또한 이어서 다룰 그룹 분류Group by, 모양 변환reshaping, 피벗 변환pivoting 등에서 유용하게 활용된다.
18.2.1. MultiIndex
객체#
다중 인덱스 객체는 보통 튜플을 이용한다. 예를 들어 아래 두 개의 리스트를 이용하여 튜플을 생성한 다음 다중 인덱스로 만들어보자.
arrays = [
["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"],
["one", "two", "one", "two", "one", "two", "one", "two"],
]
튜플 생성: 항목 8개
tuples = list(zip(*arrays))
tuples
[('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')]
다중 인덱스 객체 생성: from_tupes()
함수
튜플 리스트를 이용하여 다중 인덱스 객체를 생성할 수 있다.
index = pd.MultiIndex.from_tuples(tuples)
index
MultiIndex([('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')],
)
names
키워드 인자다중 인덱스의 각 레벨level의 이름 지정.
지정되지 않으면
None
으로 처리됨.
예를 들어 위 코드에서 사용된 각각의 레벨에 이름은 다음과 같다.
"first"
: 0-레벨 이름"second"
: 1-레벨 이름
index = pd.MultiIndex.from_tuples(tuples, names=["first", "second"])
index
MultiIndex([('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')],
names=['first', 'second'])
다중 인덱스 객체 생성: from_arrays()
함수
길이가 동일한 여러 개의 리스트로 구성된 어레이를 직접 이용할 수도 있다.
index = pd.MultiIndex.from_arrays(arrays, names=["first", "second"])
index
MultiIndex([('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')],
names=['first', 'second'])
18.2.2. 다중 인덱스 라벨label#
시리즈 생성
아래 코드는 길이가 8인 어레이를 이용하여 시리즈를 생성한다. 인덱스의 라벨은 다중 인덱스가 사용된다. 각각의 레벨에서 라벨이 연속적으로 사용되는 경우는 보다 자연스러운 표현을 위해 생략되기도 한다.
s = pd.Series(np.random.randn(8), index=index)
s
first second
bar one -0.102970
two -0.869112
baz one 0.071613
two -0.481193
foo one 0.848038
two 0.024128
qux one 0.494374
two -1.224866
dtype: float64
데이터프레임 생성
아래 코드는 8개의 행으로 이뤄진 2차원 어레이를 이용하여 데이터프레임을 생성한다.
index
또는 columns
로 여러 개의 리스트로 구성된 어레이를 지정하면
자동으로 다중 인덱스 라벨이 지정된다.
df = pd.DataFrame(np.random.randn(8, 4), index=arrays)
df
0 | 1 | 2 | 3 | ||
---|---|---|---|---|---|
bar | one | 1.011871 | 1.794615 | -0.795156 | -1.160517 |
two | -1.659252 | -0.473680 | 1.386762 | -0.747361 | |
baz | one | 2.200999 | 0.266427 | -1.502801 | -1.231025 |
two | -0.854165 | 0.270410 | -0.898856 | 0.066127 | |
foo | one | 1.971631 | 0.143811 | 0.101862 | -1.120642 |
two | 1.236258 | 1.090704 | -0.403456 | 1.793911 | |
qux | one | 1.192296 | -3.598376 | 0.913916 | 0.098270 |
two | -1.917410 | -1.085287 | -2.223167 | -0.450469 |
다중 인덱스를 열 라벨로도 활용할 수 있다. 아래 코드는 8개의 열로 이뤄진 2차원 어레이를 이용하여 데이터프레임을 생성한다.
df1 = pd.DataFrame(np.random.randn(3, 8), index=["A", "B", "C"], columns=index)
df1
first | bar | baz | foo | qux | ||||
---|---|---|---|---|---|---|---|---|
second | one | two | one | two | one | two | one | two |
A | -0.023809 | 0.903218 | 0.402345 | -1.132165 | 1.446495 | -0.190539 | 0.303528 | 1.060082 |
B | -0.588585 | 0.541489 | 0.235990 | 0.460059 | 1.419565 | -0.191601 | -0.504814 | -1.384551 |
C | -0.887831 | -0.776880 | 1.080288 | 0.549915 | 0.825186 | -0.539257 | -1.068850 | 0.504218 |
인덱스 라벨과 열 라벨 모두 다중 인덱스를 이용할 수도 있다.
동일한 길이의 리스트로 이루어진 리스트를 인덱스 또는 열의 라벨로 지정하면 다중 인덱스로 자동 지정된다.
arrays2 = [
["toto", "toto", "titi", "titi", "tata", "tata"],
["A", "B", "A", "B", "A", "B"],
]
pd.DataFrame(np.random.randn(6, 6), index=index[:6], columns=arrays2)
toto | titi | tata | |||||
---|---|---|---|---|---|---|---|
A | B | A | B | A | B | ||
first | second | ||||||
bar | one | 0.656057 | -1.181767 | 1.509824 | 0.691512 | 0.185092 | -1.020352 |
two | 1.638626 | 1.025058 | 0.233587 | 2.769262 | 0.474814 | -1.395608 | |
baz | one | -1.429578 | 0.686740 | -0.490076 | 0.629835 | 1.158276 | -0.642619 |
two | -0.861363 | -0.196854 | -0.818325 | -0.483153 | 0.069907 | 2.019037 | |
foo | one | -1.111697 | -0.706583 | -2.259861 | 0.772279 | 1.417341 | -1.998353 |
two | -0.474314 | 1.684809 | 0.128608 | -1.861478 | 0.636491 | 0.354697 |
주의사항
튜플을 라벨로 사용하는 것은 다중 인덱스와 아무 상관 없다. 단지 라벨이 튜플인 것 뿐이다.
tuples
[('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')]
pd.Series(np.random.randn(8), index=tuples)
(bar, one) -0.547467
(bar, two) 1.494266
(baz, one) 1.210512
(baz, two) -2.214762
(foo, one) 1.610649
(foo, two) -1.949249
(qux, one) -0.476863
(qux, two) -0.595795
dtype: float64
18.2.3. 다중 인덱스 레벨level#
다중 인덱스 객체의 get_level_values()
메서드를 이용하여 레벨별 인덱스 라벨을 확인할 수 있다.
0-레블 라벨
index.get_level_values(0)
Index(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], dtype='object', name='first')
레벨 이름을 이용할 수도 있다.
index.get_level_values("first")
Index(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], dtype='object', name='first')
1-레블 라벨
index.get_level_values(1)
Index(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'], dtype='object', name='second')
index.get_level_values("second")
Index(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'], dtype='object', name='second')
18.2.4. 다중 인덱스 인덱싱#
다중 인덱스를 라벨로 사용하는 시리즈와 데이터프레임의 인덱싱은 일반 인덱싱과 크게 다르지 않다.
시리즈 인덱싱
s
first second
bar one -0.102970
two -0.869112
baz one 0.071613
two -0.481193
foo one 0.848038
two 0.024128
qux one 0.494374
two -1.224866
dtype: float64
s["qux"]
second
one 0.494374
two -1.224866
dtype: float64
데이터프레임 인덱싱
df
0 | 1 | 2 | 3 | ||
---|---|---|---|---|---|
bar | one | 1.011871 | 1.794615 | -0.795156 | -1.160517 |
two | -1.659252 | -0.473680 | 1.386762 | -0.747361 | |
baz | one | 2.200999 | 0.266427 | -1.502801 | -1.231025 |
two | -0.854165 | 0.270410 | -0.898856 | 0.066127 | |
foo | one | 1.971631 | 0.143811 | 0.101862 | -1.120642 |
two | 1.236258 | 1.090704 | -0.403456 | 1.793911 | |
qux | one | 1.192296 | -3.598376 | 0.913916 | 0.098270 |
two | -1.917410 | -1.085287 | -2.223167 | -0.450469 |
df.loc["bar"]
0 | 1 | 2 | 3 | |
---|---|---|---|---|
one | 1.011871 | 1.794615 | -0.795156 | -1.160517 |
two | -1.659252 | -0.473680 | 1.386762 | -0.747361 |
레벨별로 라벨을 지정할 수 있다. 각각의 라벨은 쉼표로 구분한다.
df.loc["bar", "one"]
0 1.011871
1 1.794615
2 -0.795156
3 -1.160517
Name: (bar, one), dtype: float64
아래와 같이 할 수도 있다.
df.loc["bar"].loc["one"]
0 1.011871
1 1.794615
2 -0.795156
3 -1.160517
Name: one, dtype: float64
데이터프레임 인덱싱: 열 라벨이 다중 인덱스인 경우
df1
first | bar | baz | foo | qux | ||||
---|---|---|---|---|---|---|---|---|
second | one | two | one | two | one | two | one | two |
A | -0.023809 | 0.903218 | 0.402345 | -1.132165 | 1.446495 | -0.190539 | 0.303528 | 1.060082 |
B | -0.588585 | 0.541489 | 0.235990 | 0.460059 | 1.419565 | -0.191601 | -0.504814 | -1.384551 |
C | -0.887831 | -0.776880 | 1.080288 | 0.549915 | 0.825186 | -0.539257 | -1.068850 | 0.504218 |
df1["bar"]
second | one | two |
---|---|---|
A | -0.023809 | 0.903218 |
B | -0.588585 | 0.541489 |
C | -0.887831 | -0.776880 |
레벨별로 라벨을 지정한다. 각각의 라벨은 쉼표로 구분한다.
df1["bar", "one"]
A -0.023809
B -0.588585
C -0.887831
Name: (bar, one), dtype: float64
아래와 같이 할 수도 있다
df1["bar"]["one"]
A -0.023809
B -0.588585
C -0.887831
Name: one, dtype: float64
18.2.5. 다중 인덱스 슬라이싱#
다중 인덱스를 라벨로 사용하는 시리즈와 데이터프레임의 인덱싱은 일반 슬라이싱과 크게 다르지 않다.
df
0 | 1 | 2 | 3 | ||
---|---|---|---|---|---|
bar | one | 1.011871 | 1.794615 | -0.795156 | -1.160517 |
two | -1.659252 | -0.473680 | 1.386762 | -0.747361 | |
baz | one | 2.200999 | 0.266427 | -1.502801 | -1.231025 |
two | -0.854165 | 0.270410 | -0.898856 | 0.066127 | |
foo | one | 1.971631 | 0.143811 | 0.101862 | -1.120642 |
two | 1.236258 | 1.090704 | -0.403456 | 1.793911 | |
qux | one | 1.192296 | -3.598376 | 0.913916 | 0.098270 |
two | -1.917410 | -1.085287 | -2.223167 | -0.450469 |
0-레벨 인덱싱
df.loc["baz":"foo"]
0 | 1 | 2 | 3 | ||
---|---|---|---|---|---|
baz | one | 2.200999 | 0.266427 | -1.502801 | -1.231025 |
two | -0.854165 | 0.270410 | -0.898856 | 0.066127 | |
foo | one | 1.971631 | 0.143811 | 0.101862 | -1.120642 |
two | 1.236258 | 1.090704 | -0.403456 | 1.793911 |
(0, 1)-레벨 인덱싱
df.loc[("baz", "two"):("qux", "one")]
0 | 1 | 2 | 3 | ||
---|---|---|---|---|---|
baz | two | -0.854165 | 0.270410 | -0.898856 | 0.066127 |
foo | one | 1.971631 | 0.143811 | 0.101862 | -1.120642 |
two | 1.236258 | 1.090704 | -0.403456 | 1.793911 | |
qux | one | 1.192296 | -3.598376 | 0.913916 | 0.098270 |
튜플들의 리스트를 지정하면 리인덱싱처럼 작동한다.
df.loc[[("bar", "two"), ("qux", "one")]]
0 | 1 | 2 | 3 | ||
---|---|---|---|---|---|
bar | two | -1.659252 | -0.473680 | 1.386762 | -0.747361 |
qux | one | 1.192296 | -3.598376 | 0.913916 | 0.098270 |
이외에 slice()
함수와 pd.IndexSlice
객체를 사용하는 방법도 있지만 여기서는 다루지 않는다.
18.3. 그룹 분류: pd.groupby()
함수#
참고: Grouping section
pd.groupby()
함수는 다음 3 기능을 제공한다.
쪼개기Splitting: 데이터를 조건에 따라 여러 그룹으로 쪼개기
적용하기Applying: 그룹별로 함수 적용
조합하기Combining: 그룹별 함수 적용 결과를 조합하여 새로운 데이터프레임/시리즈 생성
df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar',
'foo', 'bar', 'foo', 'bar'],
'B': ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'C': np.random.randn(8),
'D': np.random.randn(8)})
df
A | B | C | D | |
---|---|---|---|---|
0 | foo | one | 1.587711 | -0.037118 |
1 | bar | one | -0.197821 | -0.119866 |
2 | foo | two | 2.817105 | -1.268842 |
3 | bar | three | 2.692870 | -0.819414 |
4 | foo | two | -1.005778 | 0.544011 |
5 | bar | two | 0.068631 | 1.578997 |
6 | foo | one | 0.373363 | 0.778729 |
7 | bar | three | 0.377979 | 1.125497 |
A
열에 사용된 항목 기준으로 그룹으로 분류한 후 그룹별로C
와D
열의 모든 항목의 합 계산해서 새로운 데이터프레임 생성A
경우의 수
bar
1
foo
1
df.groupby('A')[["C", "D"]].sum()
C | D | |
---|---|---|
A | ||
bar | 2.941660 | 1.765215 |
foo | 3.772401 | 0.016780 |
A
열의 항목과B
열의 항목의 조합을 기준으로 그룹으로 그룹별로C
와D
열의 모든 항목의 합 계산해서 새로운 데이터프레임 생성A
B
경우의 수
bar
one
,three
,two
3
foo
one
,two
2
df.groupby(["A", "B"]).sum()
C | D | ||
---|---|---|---|
A | B | ||
bar | one | -0.197821 | -0.119866 |
three | 3.070849 | 0.306083 | |
two | 0.068631 | 1.578997 | |
foo | one | 1.961074 | 0.741611 |
two | 1.811327 | -0.724831 |
그룹 확인
for
반복문 활용
for name, group in df.groupby(["A", "B"]):
print(name)
print(group)
('bar', 'one')
A B C D
1 bar one -0.197821 -0.119866
('bar', 'three')
A B C D
3 bar three 2.692870 -0.819414
7 bar three 0.377979 1.125497
('bar', 'two')
A B C D
5 bar two 0.068631 1.578997
('foo', 'one')
A B C D
0 foo one 1.587711 -0.037118
6 foo one 0.373363 0.778729
('foo', 'two')
A B C D
2 foo two 2.817105 -1.268842
4 foo two -1.005778 0.544011
get_group()
메서드
df.groupby(["A", "B"]).get_group(('bar', 'one'))
A | B | C | D | |
---|---|---|---|---|
1 | bar | one | -0.197821 | -0.119866 |
df.groupby(["A", "B"]).get_group(('bar', 'three'))
A | B | C | D | |
---|---|---|---|---|
3 | bar | three | 2.692870 | -0.819414 |
7 | bar | three | 0.377979 | 1.125497 |
groups
속성
df.groupby(["A", "B"]).groups
{('bar', 'one'): [1], ('bar', 'three'): [3, 7], ('bar', 'two'): [5], ('foo', 'one'): [0, 6], ('foo', 'two'): [2, 4]}
value_counts
속성
df.groupby(["A", "B"]).value_counts()
A B C D
bar one -0.197821 -0.119866 1
three 0.377979 1.125497 1
2.692870 -0.819414 1
two 0.068631 1.578997 1
foo one 0.373363 0.778729 1
1.587711 -0.037118 1
two -1.005778 0.544011 1
2.817105 -1.268842 1
dtype: int64
nunique
속성
df.groupby(["A", "B"]).nunique()
C | D | ||
---|---|---|---|
A | B | ||
bar | one | 1 | 1 |
three | 2 | 2 | |
two | 1 | 1 | |
foo | one | 2 | 2 |
two | 2 | 2 |
sort=True
키워드 인자
df.groupby(["A", "B"], sort=True).sum()
C | D | ||
---|---|---|---|
A | B | ||
bar | one | -0.197821 | -0.119866 |
three | 3.070849 | 0.306083 | |
two | 0.068631 | 1.578997 | |
foo | one | 1.961074 | 0.741611 |
two | 1.811327 | -0.724831 |
df.groupby(["A", "B"], sort=False).sum()
C | D | ||
---|---|---|---|
A | B | ||
foo | one | 1.961074 | 0.741611 |
bar | one | -0.197821 | -0.119866 |
foo | two | 1.811327 | -0.724831 |
bar | three | 3.070849 | 0.306083 |
two | 0.068631 | 1.578997 |
df.groupby(["A", "B"], sort=False).nunique()
C | D | ||
---|---|---|---|
A | B | ||
foo | one | 2 | 2 |
bar | one | 1 | 1 |
foo | two | 2 | 2 |
bar | three | 2 | 2 |
two | 1 | 1 |
그룹 연산 예제
max()
메서드
df.groupby('A')[["C", "D"]].max()
C | D | |
---|---|---|
A | ||
bar | 2.692870 | 1.578997 |
foo | 2.817105 | 0.778729 |
df.groupby(["A", "B"]).max()
C | D | ||
---|---|---|---|
A | B | ||
bar | one | -0.197821 | -0.119866 |
three | 2.692870 | 1.125497 | |
two | 0.068631 | 1.578997 | |
foo | one | 1.587711 | 0.778729 |
two | 2.817105 | 0.544011 |
mean()
메서드
df.groupby('A')[["C", "D"]].mean()
C | D | |
---|---|---|
A | ||
bar | 0.735415 | 0.441304 |
foo | 0.943100 | 0.004195 |
df.groupby(["A", "B"]).mean()
C | D | ||
---|---|---|---|
A | B | ||
bar | one | -0.197821 | -0.119866 |
three | 1.535425 | 0.153041 | |
two | 0.068631 | 1.578997 | |
foo | one | 0.980537 | 0.370805 |
two | 0.905664 | -0.362415 |
size()
메서드
df.groupby('A')[["C", "D"]].size()
A
bar 4
foo 4
dtype: int64
df.groupby(["A", "B"]).size()
A B
bar one 1
three 2
two 1
foo one 2
two 2
dtype: int64
describe()
메서드
df.groupby('A')[["C", "D"]].describe()
C | D | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | mean | std | min | 25% | 50% | 75% | max | count | mean | std | min | 25% | 50% | 75% | max | |
A | ||||||||||||||||
bar | 4.0 | 0.735415 | 1.326011 | -0.197821 | 0.002018 | 0.223305 | 0.956702 | 2.692870 | 4.0 | 0.441304 | 1.105560 | -0.819414 | -0.294753 | 0.502815 | 1.238872 | 1.578997 |
foo | 4.0 | 0.943100 | 1.638103 | -1.005778 | 0.028578 | 0.980537 | 1.895059 | 2.817105 | 4.0 | 0.004195 | 0.915357 | -1.268842 | -0.345049 | 0.253447 | 0.602691 | 0.778729 |
df.groupby(["A", "B"]).describe()
C | D | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | mean | std | min | 25% | 50% | 75% | max | count | mean | std | min | 25% | 50% | 75% | max | ||
A | B | ||||||||||||||||
bar | one | 1.0 | -0.197821 | NaN | -0.197821 | -0.197821 | -0.197821 | -0.197821 | -0.197821 | 1.0 | -0.119866 | NaN | -0.119866 | -0.119866 | -0.119866 | -0.119866 | -0.119866 |
three | 2.0 | 1.535425 | 1.636875 | 0.377979 | 0.956702 | 1.535425 | 2.114147 | 2.692870 | 2.0 | 0.153041 | 1.375259 | -0.819414 | -0.333186 | 0.153041 | 0.639269 | 1.125497 | |
two | 1.0 | 0.068631 | NaN | 0.068631 | 0.068631 | 0.068631 | 0.068631 | 0.068631 | 1.0 | 1.578997 | NaN | 1.578997 | 1.578997 | 1.578997 | 1.578997 | 1.578997 | |
foo | one | 2.0 | 0.980537 | 0.858673 | 0.373363 | 0.676950 | 0.980537 | 1.284124 | 1.587711 | 2.0 | 0.370805 | 0.576891 | -0.037118 | 0.166844 | 0.370805 | 0.574767 | 0.778729 |
two | 2.0 | 0.905664 | 2.703187 | -1.005778 | -0.050057 | 0.905664 | 1.861384 | 2.817105 | 2.0 | -0.362415 | 1.281881 | -1.268842 | -0.815629 | -0.362415 | 0.090798 | 0.544011 |
18.4. 모양 변환Reshaping#
18.4.1. 항목 재배열#
참고: Reshaping
스택
열 인덱스의 레벨을 하나 줄일 때 사용한다. 없어진 레벨은 행 인덱스의 마지막 레벨로 추가된다.
index
MultiIndex([('bar', 'one'),
('bar', 'two'),
('baz', 'one'),
('baz', 'two'),
('foo', 'one'),
('foo', 'two'),
('qux', 'one'),
('qux', 'two')],
names=['first', 'second'])
df = pd.DataFrame(np.random.randn(8, 2), index=index, columns=["A", "B"])
df
A | B | ||
---|---|---|---|
first | second | ||
bar | one | 1.532293 | 0.053124 |
two | -1.328301 | -1.943130 | |
baz | one | 1.713431 | -2.052346 |
two | -0.148125 | 2.166299 | |
foo | one | 0.251638 | 0.299314 |
two | -0.834706 | 0.250370 | |
qux | one | 0.889168 | -0.181520 |
two | -0.139113 | -0.984504 |
df2 = df[:4]
df2
A | B | ||
---|---|---|---|
first | second | ||
bar | one | 1.532293 | 0.053124 |
two | -1.328301 | -1.943130 | |
baz | one | 1.713431 | -2.052346 |
two | -0.148125 | 2.166299 |
stack()
메서드: 열이 한 개의 레벨로 구성되어 있기에stack()
메서드를 적용하면 결국 모든 열이 없어지고, 열의 라벨은 인덱스의 마지막 레벨의 라벨로 변환된다. 여기서는 결국 3중 인덱스를 사용하는 시리즈를 생성한다.
stacked = df2.stack()
stacked
first second
bar one A 1.532293
B 0.053124
two A -1.328301
B -1.943130
baz one A 1.713431
B -2.052346
two A -0.148125
B 2.166299
dtype: float64
언스택
행 인덱스의 지정된 레벨을 열의 마지막 레벨로 변환한다. 인자를 지정하지 않으면 마지막 레벨을 변환한다.
unstack()
메서드
stacked.unstack()
A | B | ||
---|---|---|---|
first | second | ||
bar | one | 1.532293 | 0.053124 |
two | -1.328301 | -1.943130 | |
baz | one | 1.713431 | -2.052346 |
two | -0.148125 | 2.166299 |
stacked.unstack().unstack()
A | B | |||
---|---|---|---|---|
second | one | two | one | two |
first | ||||
bar | 1.532293 | -1.328301 | 0.053124 | -1.943130 |
baz | 1.713431 | -0.148125 | -2.052346 | 2.166299 |
인자를 지정하면 해당 레벨을 열의 마지막 레벨로 변환한다.
stacked.unstack(0)
first | bar | baz | |
---|---|---|---|
second | |||
one | A | 1.532293 | 1.713431 |
B | 0.053124 | -2.052346 | |
two | A | -1.328301 | -0.148125 |
B | -1.943130 | 2.166299 |
stacked.unstack(1)
second | one | two | |
---|---|---|---|
first | |||
bar | A | 1.532293 | -1.328301 |
B | 0.053124 | -1.943130 | |
baz | A | 1.713431 | -0.148125 |
B | -2.052346 | 2.166299 |
18.4.2. 피버팅#
참고: Pivot Tables
pd.pivot_table()
함수
예제
import datetime
df = pd.DataFrame(
{
"A": ["one", "one", "two", "three"] * 6,
"B": ["A", "B", "C"] * 8,
"C": ["foo", "foo", "foo", "bar", "bar", "bar"] * 4,
"D": np.random.randn(24),
"E": np.random.randn(24),
}
)
df
A | B | C | D | E | |
---|---|---|---|---|---|
0 | one | A | foo | -2.878726 | -2.064460 |
1 | one | B | foo | 1.450555 | 0.130506 |
2 | two | C | foo | -1.023284 | -0.070181 |
3 | three | A | bar | 0.360537 | 1.091334 |
4 | one | B | bar | 2.076769 | -0.766590 |
5 | one | C | bar | -0.226304 | 0.575288 |
6 | two | A | foo | 0.875535 | -2.104198 |
7 | three | B | foo | -0.981223 | 0.452921 |
8 | one | C | foo | -0.254173 | -0.573222 |
9 | one | A | bar | 1.322995 | 0.695488 |
10 | two | B | bar | 0.006313 | -0.070619 |
11 | three | C | bar | 0.263893 | 0.670962 |
12 | one | A | foo | -1.089184 | 0.158075 |
13 | one | B | foo | 1.034373 | -0.508421 |
14 | two | C | foo | 0.484234 | -0.955311 |
15 | three | A | bar | 0.693513 | 1.219480 |
16 | one | B | bar | -1.147675 | -0.729457 |
17 | one | C | bar | -0.772348 | 0.525151 |
18 | two | A | foo | 0.906707 | -1.395497 |
19 | three | B | foo | 1.194608 | 0.374196 |
20 | one | C | foo | -1.908083 | -1.584192 |
21 | one | A | bar | 0.074390 | 1.095922 |
22 | two | B | bar | -0.443055 | -2.268940 |
23 | three | C | bar | -1.182320 | 0.442309 |
pd.pivot_table(df, values="D", index=["A", "B"], columns=["C"]) # aggfunc=np.mean 이 기본값
C | bar | foo | |
---|---|---|---|
A | B | ||
one | A | 0.698693 | -1.983955 |
B | 0.464547 | 1.242464 | |
C | -0.499326 | -1.081128 | |
three | A | 0.527025 | NaN |
B | NaN | 0.106693 | |
C | -0.459214 | NaN | |
two | A | NaN | 0.891121 |
B | -0.218371 | NaN | |
C | NaN | -0.269525 |
pd.pivot_table(df, values="D", index=["A", "B"], columns=["C"], aggfunc=np.sum)
C | bar | foo | |
---|---|---|---|
A | B | ||
one | A | 1.397385 | -3.967910 |
B | 0.929094 | 2.484928 | |
C | -0.998652 | -2.162256 | |
three | A | 1.054050 | NaN |
B | NaN | 0.213385 | |
C | -0.918427 | NaN | |
two | A | NaN | 1.782242 |
B | -0.436741 | NaN | |
C | NaN | -0.539050 |
DataFrame.pivot()
메서드
df
A | B | C | D | E | |
---|---|---|---|---|---|
0 | one | A | foo | -2.878726 | -2.064460 |
1 | one | B | foo | 1.450555 | 0.130506 |
2 | two | C | foo | -1.023284 | -0.070181 |
3 | three | A | bar | 0.360537 | 1.091334 |
4 | one | B | bar | 2.076769 | -0.766590 |
5 | one | C | bar | -0.226304 | 0.575288 |
6 | two | A | foo | 0.875535 | -2.104198 |
7 | three | B | foo | -0.981223 | 0.452921 |
8 | one | C | foo | -0.254173 | -0.573222 |
9 | one | A | bar | 1.322995 | 0.695488 |
10 | two | B | bar | 0.006313 | -0.070619 |
11 | three | C | bar | 0.263893 | 0.670962 |
12 | one | A | foo | -1.089184 | 0.158075 |
13 | one | B | foo | 1.034373 | -0.508421 |
14 | two | C | foo | 0.484234 | -0.955311 |
15 | three | A | bar | 0.693513 | 1.219480 |
16 | one | B | bar | -1.147675 | -0.729457 |
17 | one | C | bar | -0.772348 | 0.525151 |
18 | two | A | foo | 0.906707 | -1.395497 |
19 | three | B | foo | 1.194608 | 0.374196 |
20 | one | C | foo | -1.908083 | -1.584192 |
21 | one | A | bar | 0.074390 | 1.095922 |
22 | two | B | bar | -0.443055 | -2.268940 |
23 | three | C | bar | -1.182320 | 0.442309 |
df1 = df.groupby(['A', 'B', 'C']).sum().reset_index()
df1
A | B | C | D | E | |
---|---|---|---|---|---|
0 | one | A | bar | 1.397385 | 1.791411 |
1 | one | A | foo | -3.967910 | -1.906385 |
2 | one | B | bar | 0.929094 | -1.496047 |
3 | one | B | foo | 2.484928 | -0.377915 |
4 | one | C | bar | -0.998652 | 1.100439 |
5 | one | C | foo | -2.162256 | -2.157414 |
6 | three | A | bar | 1.054050 | 2.310814 |
7 | three | B | foo | 0.213385 | 0.827117 |
8 | three | C | bar | -0.918427 | 1.113271 |
9 | two | A | foo | 1.782242 | -3.499695 |
10 | two | B | bar | -0.436741 | -2.339559 |
11 | two | C | foo | -0.539050 | -1.025492 |
df1.pivot(index=['A', 'B'], columns='C', values="D")
C | bar | foo | |
---|---|---|---|
A | B | ||
one | A | 1.397385 | -3.967910 |
B | 0.929094 | 2.484928 | |
C | -0.998652 | -2.162256 | |
three | A | 1.054050 | NaN |
B | NaN | 0.213385 | |
C | -0.918427 | NaN | |
two | A | NaN | 1.782242 |
B | -0.436741 | NaN | |
C | NaN | -0.539050 |
18.5. 데이터셋 불러오기와 저장하기#
csv 파일 불러오기
df.to_csv("foo.csv")
csv 파일로 저장하기
참고:
read_csv()
pd.read_csv("foo.csv")
Unnamed: 0 | A | B | C | D | E | |
---|---|---|---|---|---|---|
0 | 0 | one | A | foo | -2.878726 | -2.064460 |
1 | 1 | one | B | foo | 1.450555 | 0.130506 |
2 | 2 | two | C | foo | -1.023284 | -0.070181 |
3 | 3 | three | A | bar | 0.360537 | 1.091334 |
4 | 4 | one | B | bar | 2.076769 | -0.766590 |
5 | 5 | one | C | bar | -0.226304 | 0.575288 |
6 | 6 | two | A | foo | 0.875535 | -2.104198 |
7 | 7 | three | B | foo | -0.981223 | 0.452921 |
8 | 8 | one | C | foo | -0.254173 | -0.573222 |
9 | 9 | one | A | bar | 1.322995 | 0.695488 |
10 | 10 | two | B | bar | 0.006313 | -0.070619 |
11 | 11 | three | C | bar | 0.263893 | 0.670962 |
12 | 12 | one | A | foo | -1.089184 | 0.158075 |
13 | 13 | one | B | foo | 1.034373 | -0.508421 |
14 | 14 | two | C | foo | 0.484234 | -0.955311 |
15 | 15 | three | A | bar | 0.693513 | 1.219480 |
16 | 16 | one | B | bar | -1.147675 | -0.729457 |
17 | 17 | one | C | bar | -0.772348 | 0.525151 |
18 | 18 | two | A | foo | 0.906707 | -1.395497 |
19 | 19 | three | B | foo | 1.194608 | 0.374196 |
20 | 20 | one | C | foo | -1.908083 | -1.584192 |
21 | 21 | one | A | bar | 0.074390 | 1.095922 |
22 | 22 | two | B | bar | -0.443055 | -2.268940 |
23 | 23 | three | C | bar | -1.182320 | 0.442309 |
엑셀 파일 불러오기
df.to_excel("foo.xlsx", sheet_name="Sheet1")
엑셀 파일로 저장하기
참고:
read_excel()
pd.read_excel("foo.xlsx", "Sheet1", index_col=None, na_values=["NA"])
Unnamed: 0 | A | B | C | D | E | |
---|---|---|---|---|---|---|
0 | 0 | one | A | foo | -2.878726 | -2.064460 |
1 | 1 | one | B | foo | 1.450555 | 0.130506 |
2 | 2 | two | C | foo | -1.023284 | -0.070181 |
3 | 3 | three | A | bar | 0.360537 | 1.091334 |
4 | 4 | one | B | bar | 2.076769 | -0.766590 |
5 | 5 | one | C | bar | -0.226304 | 0.575288 |
6 | 6 | two | A | foo | 0.875535 | -2.104198 |
7 | 7 | three | B | foo | -0.981223 | 0.452921 |
8 | 8 | one | C | foo | -0.254173 | -0.573222 |
9 | 9 | one | A | bar | 1.322995 | 0.695488 |
10 | 10 | two | B | bar | 0.006313 | -0.070619 |
11 | 11 | three | C | bar | 0.263893 | 0.670962 |
12 | 12 | one | A | foo | -1.089184 | 0.158075 |
13 | 13 | one | B | foo | 1.034373 | -0.508421 |
14 | 14 | two | C | foo | 0.484234 | -0.955311 |
15 | 15 | three | A | bar | 0.693513 | 1.219480 |
16 | 16 | one | B | bar | -1.147675 | -0.729457 |
17 | 17 | one | C | bar | -0.772348 | 0.525151 |
18 | 18 | two | A | foo | 0.906707 | -1.395497 |
19 | 19 | three | B | foo | 1.194608 | 0.374196 |
20 | 20 | one | C | foo | -1.908083 | -1.584192 |
21 | 21 | one | A | bar | 0.074390 | 1.095922 |
22 | 22 | two | B | bar | -0.443055 | -2.268940 |
23 | 23 | three | C | bar | -1.182320 | 0.442309 |