728x90
반응형

 이전 포스트에서 DataFrame의 생김새와 부위별 이름에 대해 알아보았다. DataFrame의 가장 큰 특징은 index가 존재한다는 것이고, 이 index를 얼마나 잘 가지고 노느냐에 따라 DataFrame을 얼마나 효율적으로 사용할 수 있는지가 나뉘게 된다.

 

 

데이터 프레임과 인덱스

 Pandas에 대해 흔히들 가지고 있는 오해가 Pandas는 순차적으로 데이터를 조회하기 때문에, 데이터 전처리 속도가 매우 느리다는 것이다.

 이 말은 반은 맞고, 반은 틀리다고 할 수 있는데, DataFrame에서 특정 데이터를 단순하게 조회하면, 순서대로 하나하나 조회하기 때문에 속도가 매우 느려지고, 도리어 이 특징을 이용해서, 데이터 전처리 속도를 줄일 수도 있다.

 그러나, 인덱스를 사용하여 조회를 하게 된다면, 순차적 조회가 아닌 한 번에 index에 해당하는 값을 가지고 오기 때문에 조회 속도가 엄청 빨라진다.

 그러므로, Pandas를 사용해야 하는 데이터 분석가라면 반드시 이 인덱스를 잘 가지고 놀 수 있어야 한다.

 

 

 

 

1. DataFrame 생성 시, 원하는 Index 부여하기

  • index는 DataFrame을 생성하면서 부여할 수도 있고, DataFrame을 생성한 후에도 바꿔줄 수 있다.
  • 다음과 같은 데이터 셋을 만들어보자.
import pandas as pd
name_list = ["박명수", "유재석", "노홍철", "길", "정준하", "정형돈", "하하"]
math_list = [65, 95, 70, 80, 100, 85, 60]
english_list = [75, 80, 85, 90, 65, 75, 100]
class_list = [1, 2, 1, 2, 2, 2, 1]
index_list = list(range(10, 24, 2))

exam = pd.DataFrame({"name":name_list, "math":math_list, "english":english_list,
                     "class":class_list}, index=index_list)
exam

  • range(start, end, by): start부터 end까지 값을 by 간격으로 만들 준비를 한다.
    (list 함수 같은 것으로 가동해주지 않으면, 대기 상태를 유지한다)
  • 생성된 데이터 프레임을 보듯, 데이터 프레임 생성 시, index 파라미터에 넣어준 list를 index로 부여한다.

 

 

 

 

2. 내가 원하는 칼럼을 index로 부여하기

  • 이미 index가 정해졌다 할지라도, index는 내가 원하는 칼럼을 index로 만들어줄 수 있다.
exam.set_index("name", inplace=True)
exam

  • DataFrame.set_index(column, drop=True, append=False, inplace=False): set_index()는 말 그대로, 내가 원하는 칼럼을 index로 설정해주는 함수다.
  • drop 파라미터는 기존 칼럼을 index로 넣을 때, 기존 칼럼을 말 그대로 버려버릴지를 묻는 것이다.
  • append 파라미터는 기존 인덱스에 내가 원하는 칼럼까지 추가해서 인덱스를 만들지를 묻는 것이다.
  • inplace 파라미터는 원본 데이터에 덮어씌울지를 물어보는 것이다. 여기서는 inplace = True를 하였으므로, index가 바뀐 것을 바로 원본에 적용하였다.
  • 중복되는 값이라 할지라도 index로 만들 수 있다.
exam.set_index("class", inplace=True)
exam

  • 데이터 프레임의 인덱스에 대해 "중복이 돼서는 안 되는 유니크한 값이어야 한다."라 오해를 하는 경우가 종종 있는데, 위에서 보시다시피 중복이 가능하다. 이는, 데이터 프레임의 인덱스의 특징이며, 이 특징을 잘 이용하는 것이 중요하다.
  • 데이터 프레임의 인덱스는 중복 가능하므로, 조회 시, 해당 인덱스에 해당하는 값을 모두 가지고 온다.
exam.loc[2]

  • DataFrame.loc[index]: index에 해당하는 행을 조회하는 방법으로 추후 자세히 다루도록 하겠다.

 

 

 

 

3. 인덱스 초기화

  • 무한도전 멤버들의 이름을 인덱스로 했었다가 class로 인덱스를 설정하니, 무한도전 멤버들의 이름이 사라져 버렸다.
  • 이는 DataFrame.set_index()는 기본적으로 기존 index를 없애는 것을 전재로 하기 때문이다.
  • 이러한 일을 막기 위해선 set_index()를 하기 전에 인덱스를 초기화해줘야 한다.
exam.reset_index(drop = False, inplace = True)
exam

  • DataFrame.reset_index(drop=False, inplace=False): reset_index는 인덱스를 말 그대로 초기화시켜버린다.
  • drop 파라미터는 기존의 index를 버릴지 말지를 결정하는 파라미터다
  • 무한도전 멤버들의 이름이 index인 상태에서 reset_index()하고 set_index()를 하였다면, 이번처럼 기존 인덱스가 날아가버리는 일을 막을 수 있다.

 

 

 

 

4. 새로운 list를 인덱스로 부여하고 인덱스를 조작해보자

  • 처음에 만들었던, name_list를 index로 부여하여, 무한도전 멤버의 이름이 index인 상태로 돌아가 보자.
exam.index = name_list
exam

  • DataFrame.index: DataFrame의 index를 조작할 수 있다.
  • 이전에는 index의 이름이 name으로 나왔으나, index는 본래 이름이 따로 없기 때문에 index의 이름이 없는 상태로 출력된 것을 볼 수 있다.

4.1. 인덱스 이름 부여

exam.index.name = "name"
exam

  • DataFrame.index는 뒤에 다른 함수들을 붙여 추가적인 기능들을 실행할 수 있다.
  • 이번에는 DataFrame.index.name으로 하여 index의 이름을 부여해보았다.

4.2. 인덱스 데이터 추출

>>> exam.index
Index(['박명수', '유재석', '노홍철', '길', '정준하', '정형돈', '하하'], dtype='object', name='name')
  • list를 index에 넣었듯, array로 index를 뽑아낼 수도 있다.
  • 이러한 index 조작은 데이터 프레임을 다룰 때, 상당히 쓸모 있는 기술이므로 꼭 숙지하도록 하자.

 

 

 

 

5. 멀티 인덱스(Multi index)와 인덱스를 기준으로 정렬

  • 멀티 인덱스는 말 그대로 index를 한 번에 여러 개 사용하는 방법이다.
  • 무한도전 멤버의 이름을 칼럼으로 되돌리고, class, name으로 멀티 인덱싱을 해보자.
exam.reset_index(drop=False, inplace=True)
exam.set_index(["class", "name"], inplace = True)
exam

  • 멀티 인덱스는 set_index(column)에서 칼럼을 여러 개 넣어서 실시할 수 있다.
  • 멀티 인덱스를 하고 나니, class 2의 길, 정준하, 정형돈의 class가 하나로 붙어 깔끔하게 나온 것을 볼 수 있다.
  • 그러나, 썩 깔끔해 보이지 않으므로 인덱스를 기준으로 정렬시켜보자.

5.1. 인덱스 기준 정렬

exam.sort_index(inplace=True)
exam

  • DataFrame.sort_index(ascending=True, inplace=False): 말 그대로 index순으로 정렬(sort)한다.
  • ascending 파라미터는 오름차순, 내림차순을 의미하며, 기본적으로 오름차순 정렬이 실행된다.

5.2. 멀티 인덱스의 실제 모습

  • 멀티 인덱스를 실행하게 되면, 데이터의 형태를 보다 쉽게 파악할 수 있다는 장점이 있다. 때문에 멀티 인덱스는 group_by를 하여 두 집단 이상의 기술 통계량을 볼 때, 멀티 인덱스로 출력되게 된다.
  • 멀티 인덱스를 하면, class는 하나의 index로 뭉친 것처럼 보이는데, 눈에만 저렇게 보이지 실제로는 따로 떨어져 있다.
>>> exam.index
MultiIndex([(1, '노홍철'),
            (1, '박명수'),
            (1,  '하하'),
            (2,   '길'),
            (2, '유재석'),
            (2, '정준하'),
            (2, '정형돈')],
           names=['class', 'name'])
  • exam의 index를 보면, 튜플로 묶여 있는 것을 볼 수 있다.

5.3. 멀티 인덱스 해제

exam.reset_index(drop=False)

  • 멀티 인덱스 해제는 reset_index()를 하여 쉽게 할 수 있다.

 

 

 

 지금까지 판다스에서 인덱스를 가지고 노는 법에 대해 학습해보았다. 판다스에서 인덱스를 얼마나 잘 활용하느냐에 따라 판다스의 속도는 크게 변하므로, 인덱스를 잘 활용하길 바란다.

728x90
반응형
728x90
반응형

판다스(Pandas) 소개

 파이썬을 처음 사용하는 데이터 분석가가 제일 먼저 공부해야 할 라이브러리를 한 가지 꼽으라면, 많은 사람들이 판다스(Pandas)를 선택할 것이다.

 판다스는 R과 마찬가지로 데이터 프레임(DataFrame)을 사용해서, 데이터를 시각화, 분석을 할 수 있는데, R의 데이터 프레임이 그렇듯 매우 직관적이고, 데이터를 가지고 놀기 좋은 R의 기능을 대부분 사용할 수 있기 때문에 데이터 분석가에게 있어 필수 라이브러리라고 할 수 있다.

 

 사족으로 판다스라고 하면, 동물인 판다가 먼저 떠오를 텐데, 판다스는 동물에서 따온 이름이 아닌, 계량 경제학에서 사용하는 "패널 데이터(Panner Data)"에서 따온 이름이다.

 사회 과학에서 자주 다뤄지는 패널 데이터를 간략히 설명하자면, 횡단 데이터인 한 시점에서의 데이터 셋이 종단 데이터로 규칙적인 기간을 간격으로 여러 개 존재하는 데이터를 말한다. 즉, 종단 + 횡단의 성격을 갖는 데이터가 패널 데이터다. 이는 판다스가 한 시점에서 뿐만이 아닌 시계열 데이터에도 강한 면모를 가진다는 뜻이기도 하다.

 

 판다스는 대용량 데이터를 다룰 때나, 서비스를 위해 0.5초, 1초 내의 빠른 연산이 필요한 상황에선 취약한 모습을 보이기 때문에 만능이라고 할 수는 없으나, 판다스는 데이터의 흐름이나 데이터의 특징 파악이 매우 쉬우므로, 먼저 판다스로 코드를 짜고, 속도가 매우 빠른 Numpy로 코드를 수정하면, 이를 쉽게 해결할 수 있다.

 

 

 

 

1. 판다스의 데이터 타입

  • 판다스는 크게 2개의 고유 데이터 타입을 가지고 있다.
  • 하나는 데이터 프레임(DataFrame)이고, 다른 하나는 시리즈(Series)이다.
  • 어떻게 생겼는지만 간략히 봐보자.
import pandas as pd
from sklearn.datasets import load_iris

# 붓꽃(iris) 데이터를 가져와보자.
iris_dict = load_iris()

DF = pd.DataFrame(iris_dict["data"], columns=iris_dict["feature_names"])
DF

  • 위 표가 데이터 프레임이다.
  • 데이터 프레임은 마치 액셀처럼 이쁘게 표로 나눠져 있는 형태다.
  • 엑셀과 차이라면, 데이터 프레임은 모든 데이터를 한 번에 보여주지 않는다는 것이다.
  • 데이터 프레임은 한 번에 최대 60개 행까지 보여준다.
>>> DF[:60]

>>> DF["sepal length (cm)"]
0      5.1
1      4.9
2      4.7
3      4.6
4      5.0
      ... 
145    6.7
146    6.3
147    6.5
148    6.2
149    5.9
Name: sepal length (cm), Length: 150, dtype: float64
  • 시리즈는 array와 굉장히 비슷하며, 데이터 프레임은 길이가 동일한 시리즈가 열의 숫자만큼 붙어있다고 생각해도 좋다.
  • array와의 차이점은 array의 index는 무조건 0부터 시작하지만, 시리즈는 그렇지 않다는 것이다. 또한 데이터 프레임이나 시리즈는 멀티 인덱스라 하여, 2개의 칼럼을 인덱스로 사용할 수 있다.

 

 

 

 다음 포스트에서는 본격적으로 데이터 프레임을 다뤄보도록 하겠다.

728x90
반응형
728x90
반응형

 자, 드디어 마지막 기초 자료형인 DataFrame이다. DataFrame은 pandas의 대표적인 Type이며, R을 공부해 본 사람이라면, 상당히 친숙하게 느껴지는 단어일 것이다.

 pandas의 DataFrame은 R의 Dataframe을 Python에서도 사용해보기 위해 만들어졌으며, R에서 할 수 있는 대부분의 기능을 판다스에서도 구현할 수 있다.

 이번 포스트에서는 데이터 분석가들의 필수 Type인 DataFrame이 어떻게 생겼는지와 아주 대략적인 대표 기능만 살펴보고 바로 넘어가도록 하자.

 

 

 먼저 DataFrame을 만들어보자.

  • DataFrame을 만드는 방법은 크게 2가지가 있다.
    1.  길이가 동일한 list들을 컬럼 하나하나에 배정하는 방법
    2. M*N 행렬 형태의 Data(Array, Tupple)를 DataFrame에 넣는 방법
# pandas 모듈을 가지고 오자
>>> import pandas as pd
>>> import numpy as np


# 1. 길이가 동일한 list들을 DataFrame에 넣어보자
# DataFrame에 들어갈 길이가 같은 list들을 만들자
>>> name = ["민철", "기훈", "재성", "현택", "윤기"]
>>> math = [40, 60, 80, 75, 65]
>>> english = [75, 80, 65, 80, 70]
>>> science = [85, 70, 75, 80, 60]

# list들을 이용해서 DataFrame을 만드는 경우는 다음과 같다
>>> DF = pd.DataFrame({"name":name, "math":math, "english":english, "science":science})
>>> DF

name	math	english	science
0	민철	40	75	85
1	기훈	60	80	70
2	재성	80	65	75
3	현택	75	80	80
4	윤기	65	70	60



# 2. array를 이용해서 DataFrame을 만들어보자.
# 10, 100 사이의 임의의 값으로 만들어진 행렬을 생성하자
>>> row_number = 50
>>> score_mat = np.random.randint(10, 100, size=(row_number, 4))

# ID를 만들어보자
>>> ID_list = []
>>> for i in range(row_number):
    
	    ID = "A" + str(i)
    	ID_list.append(ID)
    
# shape을 맞춰서 ID_array와 score_mat을 병합시켜보자
>>> ID_array = np.array(ID_list)
>>> ID_array = ID_array.reshape((50, 1))

>>> data_array = np.hstack((ID_array, score_mat))

# array를 DataFrame을 만들어보자
>>> DF2 = pd.DataFrame(data_array, columns=["ID", "math", "English", "science", "Korean"])
# 생성한 DataFrame의 상위 10개만 출력해보자
>>> DF2.head(10)


ID	math	English	science	Korean
0	A0	35	38	62	51
1	A1	52	29	40	93
2	A2	28	16	99	71
3	A3	93	42	61	48
4	A4	23	60	39	48
5	A5	93	96	16	55
6	A6	13	69	88	90
7	A7	31	18	80	30
8	A8	59	12	66	93
9	A9	54	70	57	38
  • DataFrame을 처음 보면 마치 엑셀에서 우리가 일반적으로 만들던 표랑 굉장히 유사하다는 것을 알 수 있다.
  • DataFrame에는 각 열(Column)별로 동일한 데이터 타입을 넣을 수 있다.
  • pd.DataFrame() 함수를 통해 DataFrame을 만들 수 있다.
  • np.random.randint(시작 값, 끝 값, 형태) 함수는 시작 값, 끝 값 사이에서 랜덤한 값이 담긴 array를 생성한다.
  • np.hstack((array1, array2)) 함수는 두 array를 열을 기준으로 병합한다.
  • DataFrame.head(숫자) 함수는 내가 숫자만큼 DataFrame을 출력한다.

 

 

DataFrame의 컬럼별 dtype을 확인해보자

# DataFrame의 data type을 확인해보자
>>> DF2.dtypes
ID         object
math       object
English    object
science    object
Korean     object
dtype: object


# math, English, science, Korean 컬럼을 정수 type으로 바꿔보자
>>> DF2["math"] = DF2["math"].astype("int64")
>>> DF2["English"] = DF2["English"].astype("int64")
>>> DF2["science"] = DF2["science"].astype("int64")
>>> DF2["Korean"] = DF2["Korean"].astype("int64")
>>> DF2.dtypes
ID         object
math        int64
English     int64
science     int64
Korean      int64
dtype: object
  • DataFrame.dtypes 함수를 통해 DataFrame의 각 컬럼들의 Type을 확인할 수 있다.
  • DataFrame["컬럼"].astype("바꿀 dtype") 함수를 통해 DataFrame의 해당 컬럼 dtype을 바꿀 수 있다.

 

 

DataFrame을 Slicing 해보자.

# 10번 row부터 20번 row까지 출력해보자
>>> DF2[10:20]
	ID	math	English	science	Korean
10	A10	78	24	99	79
11	A11	41	87	83	10
12	A12	61	71	31	78
13	A13	74	80	32	99
14	A14	20	19	95	38
15	A15	24	67	22	24
16	A16	39	53	41	82
17	A17	34	57	52	67
18	A18	34	60	27	73
19	A19	27	35	91	81




# 수학 80점 이상인 Row만 출력해보자
>>> DF2[DF2["math"] >= 80]
	ID	math	English	science	Korean
2	A2	90	70	70	72
4	A4	90	27	64	42
8	A8	99	21	71	92
9	A9	89	61	11	30
28	A28	81	29	27	86
32	A32	84	19	89	31
44	A44	97	73	36	78
45	A45	80	95	54	12
48	A48	86	19	99	83
  • pandas의 dataFrame은 Numpy의 array와 동일한 방법으로 Slicing 할 수 있으며, 내가 원하는 조건에 대한 Row도 쉽게 가져올 수 있다.

 

 

 이번 포스트에서는 DataFrame에 대해 아주 간략하게 훑어만 봤는데, 설명을 보다 보면 설명이 지나치게 부족하지 않는가? 하는 생각이 들 것이다. 

 pandas의 DataFrame 역시 Numpy의 array와 마찬가지로 그 영역이 매우 크기 때문에 따로 카테고리를 만들어서 세세하게 설명하고자 한다.

 이번 포스트에서는 맛보기로 DataFrame이 어떻게 생겼는지만 인식하는 수준에서 끝내고, 추후 Python-pandas 카테고리의 포스트에서 pandas의 각 기능들을 세세하게 따져보도록 하겠다.

 
728x90
반응형

+ Recent posts