Py) 기초 - Pandas(Series)

Py) 기초 - Pandas(Series)

파이썬 기반 데이터분석을 위하여 Pandas 라이브러리의 시리즈(Series) 객체에 대해 간단하게 알아본다.


개요

Pandas 라이브러리의 기본 객체이자 1차원 객체인 시리즈(Series) 객체는 1차원 배열과 유사하지만, 각각의 원소에 라벨을 붙일 수 있다. 이 라벨을 통해 인덱싱(indexing)이 가능하며, 인덱싱을 통해 원소에 접근할 수 있다. 그리고 NumPy 의 어레이 객체보다 강력하고 다양한 메서드를 지원하며 심지어 간단한 그래프도 쉽게 그릴 수 있다.

시리즈는 인덱스와 값으로 이루어져 있으며 각 요소는 .index와 .values 어트리뷰트로 접근할 수 있다.
Pandas 시리즈 구조

생성

시리즈 객체의 생성은 Series() 함수에 주로 리스트나 NumPy 어레이 객체를 입력으로 넣어 할 수 있으며 필요시 인덱스를 각 원소의 개수만큼 할당할 수 있다.

비어있는 시리즈 객체를 생성할 경우 함수 내부에 아무것도 쓰지 않는다.

1
2
pd.Series()
## Series([], dtype: float64)

다음은 리스트와 NumPy 어레이를 사용하여 시리즈 객체를 생성하는 예제이다. 리스트도 중첩이 아니고 어레이도 1차원을 입력으로 하는 것을 알 수 있다.

1
2
3
4
5
6
7
8
9
10
11
pd.Series([100, 200, 300])
## 0 100
## 1 200
## 2 300
## dtype: int64

pd.Series(np.array([100, 200, 300]))
## 0 100
## 1 200
## 2 300
## dtype: int32

상기 결과를 보면 기본 객체나 NumPy 객체와는 다르게 인덱스가 직접적으로 표기된 것을 알 수 있다. 이것이 Pandas 객체가 다른 객체와 차별화 되는 요소라고 할 수 있겠다. Pandas 객체의 경우 인덱스를 이렇게 확인할 수 있고 원하는 인덱스로 바꿀 수도 있으며 인덱스기반의 다양한 연산 또한 가능하다.

인덱스를 지정하는 시리즈 객체 생성은 다음과 같다.

1
2
3
4
5
6
pd.Series([100, 200, 300],
index = ["A", "B", "C"])
## A 100
## B 200
## C 300
## dtype: int64

인덱스를 지정하여 시리즈를 생성하고자 한다면 딕셔너리 객체를 사용할수도 있다.

1
2
3
4
5
pd.Series({"A": 100, "B": 200, "C": 300})
## A 100
## B 200
## C 300
## dtype: int64

인덱싱

시리즈 객체의 인덱싱은 크게 인덱서(indexer)를 사용하는 것과 사용하지 않는 것이 있다.

기본 인덱싱

시리즈 객체 뒤에 대괄호를 사용하고 대괄호 내부에 인덱스를 명시하면 관련 원소가 반환된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
ser1 = pd.Series([100, 200, 300, 500, 400])
ser1
## 0 100
## 1 200
## 2 300
## 3 500
## 4 400
## dtype: int64

ser1[0]
## 100

ser1[:2]
## 0 100
## 1 200
## dtype: int64

ser1[[1, 3]]
## 1 200
## 3 500
## dtype: int64

ser1[:-1]
## 0 100
## 1 200
## 2 300
## 3 500
## dtype: int64

가장 마지막 원소를 뜻하는 “-1”의 경우 범위 지정이 아닌 단독으로 사용하면 다음과 같이 “KeyError”가 발생한다. 이는 -1 이라는 인덱스가 없기 때문이다.

1
2
3
4
5
6
ser1[-1]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\anaconda3\lib\site-packages\pandas\core\indexes\range.py in get_loc(self, key, method, tolerance)
...
KeyError: -1

특수하게 인덱스에 -1이 있다면 다음과 같이 정상동작 한다.

1
2
3
4
5
6
7
8
ser2 = pd.Series([5, 6], index = [-1, -3])
ser2
## -1 5
## -3 6
## dtype: int64

ser2[-1]
## 5

인덱서의 사용

인덱서는 순수하게 정수만 사용가능한 .iloc[]와 다양한 입력을 받는 .loc[] 두 가지가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ser3 = pd.Series([150, 250, 350, 450])
ser3
## 0 150
## 1 250
## 2 350
## 3 450
## dtype: int64

ser3.iloc[0]
## 150

ser3.iloc[:3]
## 0 150
## 1 250
## 2 350
## dtype: int64

ser3.iloc[-2:]
## 2 350
## 3 450
## dtype: int64

ser3.iloc[[0, -1]]
## 0 150
## 3 450
## dtype: int64

.loc[] 인덱서를 사용하면서 연속 범위를 지정하는 경우 .iloc[]와 다르게 마지막에 표기하는 범위까지 포함한다. 이 부분을 헷갈리지 않게 사용시 주의하도록 하자.

1
2
3
4
5
6
7
8
9
ser3.loc[0]
## 150

ser3.loc[:3]
## 0 150
## 1 250
## 2 350
## 3 450
## dtype: int64

필터링

시리즈 객체의 필터링은 .loc[] 인덱서를 사용하는 경우와 그렇지 않은 경우로 나뉘어진다. 그러나 실제 사용시 크게 체감을 느끼지 못하기 때문에 많이들 인덱서를 사용하지 않는 방향으로 코드를 작성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ser3 = pd.Series([150, 250, 350, 450])
ser3[ser3 > 300]
## 2 350
## 3 450
## dtype: int64

ser3[ser3 == 350]
## 2 350
## dtype: int64

ser3[ser3 != 350]
## 0 150
## 1 250
## 3 450
## dtype: int64

ser3.loc[ser3 > 300]
## 2 350
## 3 450
## dtype: int64

ser3.loc[ser3 == 350]
## 2 350
## dtype: int64

ser3.loc[ser3 != 350]
## 0 150
## 1 250
## 3 450
## dtype: int64

상기 필터링 예제 이외에도 문자열 원소와 관련된 필터링, 2개 이상의 조건, 관련 메서드를 활용한 필터링이 있으나 데이터프레임의 필터링과 함께 Pandas(필터링) 게시글 에서 다룬다.

메서드

시리즈는 지원하는 메서드가 너무 많아 별도의 게시글에서 다룰 예정이다. 관련 내용은 Pandas 공식 문서 페이지를 참고하도록 하자.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×