Python 공부 기록-9

김시헌·2025년 4월 3일

시리즈와 Map

replace 메서드로 콤마를 제거하고 int 함수로 타입을 변경한다.

코드

from pandas import Series

def remove_comma(x):
  return int(x.replace(",", ""))

s = Series(["1,234", "5,678", "9,876"])
result = s.map(remove_comma)
print(result)

실행 결과
0 1234
1 5678
2 9876
dtype: int64

출력되는 결과를 참고하면 result에는 int64 타입의 값이 들어 있는 것을 알 수 있다.

map 메서드를 사용해서 수치형 데이터를 범주형 데이터로 구분해 보자. 바인딩된 값이 5000보다 크면 '크다', 그렇지 않으면 '작다'라는 카테고리로 분류해 보자. 시리즈에는 정수 데이터가 저장되어있다.

코드

def is_greater_than_5000(x):
  if x > 5000:
   return "크다"
  else:
    return "작다"

s = Series([1234, 5678, 9876])
s = s.map(is_greater_than_5000)
print(s)

실행 결과
0 작다
1 크다
2 크다
dtype: object

라인 1-5: 분류에 사용할 함수를 하나 정의한다. 함수는 반드시 하나의 파라미터를 입력받아야 합한다. 파라미터 x에는 시리즈에 저장된 값이 차례로 입력되고, 비교 연산의 결과 "크다", "작다"는 문자열이 저장된 시리즈를 반환한다.

시리즈 필터링

이번에는 시리즈 객체에 비교 연산을 적용해 보자. 비교 연산의 종류로는 크다, 작다, 같다, 다르다 등이 있다. 간단한 예를 통해서 비교 연산을 익혀 보자. 삼성전자의 5일 종가가 시리즈 객체로 표현되어 있을 때 이를 42,000원과 비교해 보자.

코드

from pandas import Series

data = [42500, 42550, 41800, 42550, 42650]
index = ['2019-05-31', '2019-05-30', '2019-05-29', '2019-05-28', '2019-05-27']
s = Series(data=data, index=index)
cond = s > 42000
print(cond)

실행 결과
2019-05-31 True
2019-05-30 True
2019-05-29 False
2019-05-28 True
2019-05-27 True
dtype: bool

라인 6: 시리즈 객체의 각 데이터가 42000보다 큰지 비교한다.

라인 7: 비교 연산의 결과가 저장된 시리즈를 출력한다.

비교 연산의 결괏값 역시 모든 데이터에 대해 적용되며 True 또는 False의 데이터가 시리즈 타입으로 표현된다.

이번에는 시가와 종가를 시리즈 객체로 표현한 후 종가가 시가보다 큰지를 비교해 보자.

코드

close = data = [42500, 42550, 41800, 42550, 42650]
open = data = [42600, 42200, 41850, 42550, 42500]
index = ['2019-05-31', '2019-05-30', '2019-05-29', '2019-05-28', '2019-05-27']

open = Series(data=open, index=index)
close = Series(data=close, index=index)

cond = close > open
print(cond)

실행 결과
2019-05-31 False
2019-05-30 True
2019-05-29 False
2019-05-28 False
2019-05-27 True
dtype: bool

코드

cond = close > open
print(close[cond])

실행 결과
2019-05-30 42550
2019-05-27 42650
dtype: int64

만약 종가가 시가보다 높았던 상승 마감한 날의 종가를 출력하려면 어떻게 해야 할까? 앞에서 배운 불리언 색인 기능을 사용하면 된다

코드

cond = close > open
print(close[cond])

실행 결과
2019-05-30 42550
2019-05-27 42650
dtype: int64

상승 마감한 날짜만을 출력할 수도 있다. index에 조건을 연결하면 조건이 참인 날짜만 선택된다. 혹은 조건으로 시리즈를 필터링한 다음 인덱스를 가져올 수도 있다. 두 가지 모두 출력되는 결과는 같다.

코드

print(close.index[close > open])
print(close[close > open].index)

실행 결과
Index(['2019-05-30', '2019-05-27'], dtype='object')
Index(['2019-05-30', '2019-05-27'], dtype='object')

이번에는 종가가 시가보다 높은 날의 거래일과 변동폭을 출력해 보자. 여기서 변동폭은 '종가-시가'로 정의한다. 먼저 변동폭을 시리즈 객체로 표현한 후 조건으로 데이터를 슬라이싱한다.

코드

close = [42500, 42550, 41800, 42550, 42650]
open = [42600, 42200, 41850, 42550, 42500]
index = ['2019-05-31', '2019-05-30', '2019-05-29', '2019-05-28', '2019-05-27']

open = Series(data=open, index=index)
close = Series(data=close, index=index)
diff = close - open
print(diff[close > open])

실행 결과
2019-05-30 350
2019-05-27 150
dtype: int64

라인 7: 각 거래일의 변동폭을 시리즈 객체로 생성한다.

라인 8: 각 거래일의 종가와 시가를 비교하고 시리즈 객체에 대해서 불리언 색인을 적용한다. 코드가 간단하기 때문에 변수에 값을 바인딩하지 않고 한 줄에 표현했다.

정렬 및 순위

이번 절에서는 시리즈 객체의 정렬에 대해 알아보자. 표와 같이 4개 종목의 PER 데이터가 시리즈 객체로 구성돼 있다고 가정한다.

시리즈 객체는 sort_values라는 자체 정렬 메서드를 가진다. 따라서 정렬하고 싶은 시리즈 객체에서 sort_values 메서드를 호출하기만 하면 데이터를 기준으로 오름차순으로 정렬된다. 만약 큰 값에서 작은 값으로 내림차순 정렬하고 싶다면 ascending=False라고 함수 기본 인자를 설정하면 된다.

코드

from pandas import Series

data = [3.1, 2.0, 10.1, 5.1]
index = ['000010', '000020', '000030', '000040']
s = Series(data=data, index=index)
print(s)

s1 = s.sort_values()
print(s1)

s2 = s.sort_values(ascending=False)
print(s2)

실행 결과
000010 3.1
000020 2.0
000030 10.1
000040 5.1
dtype: float64
000020 2.0
000010 3.1
000040 5.1
000030 10.1
dtype: float64
000030 10.1
000040 5.1
000010 3.1
000020 2.0
dtype: float64

라인 5: 시리즈 객체를 생성합니다. 6자리의 종목코드가 인덱스이고 PER 값이 데이터인 시리즈 객체를 생성한다.

라인 9: 시리즈 객체를 오름차순으로 정렬한 새로운 시리즈 객체를 생성하고 이를 s1이라는 변수가 바인딩한다.

라인 13: 시리즈 객체를 내림차순으로 정렬한 새로운 시리즈 객체를 생성하고 이를 s2라는 변수가 바인딩한다.

출력값을 참고하면 원본 시리즈 객체 s와 오름차순 정렬된 s1 시리즈 객체 내림차순 정렬된 s2 시리즈 객체를 확인할 수 있다.

이번에는 시리즈 객체의 데이터 값을 기준으로 순위를 매겨보자. 예를 들어 표와 같이 4개의 주식 종목에 대한 PER 데이터가 있을 때 PER 값이 낮은 순으로 순위를 매겨 보고 싶다면. 앞서 배운 정렬과 달리 데이터의 위치는 그대로 유지한 채 순위만 추가한다는 점이 다르다.

시리즈 객체는 순위를 매기기 위한 rank 메서드를 제공한다. 시리즈 객체의 rank 메서드는 기본적으로 값이 작은 데이터를 1순위로 지정한다.

코드

data = [3.1, 2.0, 10.1, 3.1]
index = ['000010', '000020', '000030', '000040']
s = Series(data=data, index=index)
print(s.rank())

실행 결과
000010 2.5
000020 1.0
000030 4.0
000040 2.5
dtype: float64

만약 값이 큰 데이터를 1등으로 순위로 매기려면 rank 메서드를 호출할 때 ascending=False 옵션을 넣어주면 된다.

코드

print(s.rank(ascending=False))

실행 결과
000010 2.5
000020 4.0
000030 1.0
000040 2.5
dtype: float64

0개의 댓글