Python pandas 데이터 생성, 로딩과 저장, 색인 관리하는 법
데이터 준비 1단계

지난 시간에는 pandas Series 사용법을 알아보았습니다. Python pandas에서 시리즈(Series)가 1차원 자료 구조라면 데이터 프레임(DataFrame)은 2차원 자료 구조입니다. 2차원이라는 뜻은 자료 구조가 표 같은 스프레드시트 형식처럼 행과 열로 되어있다는 의미입니다.
pandas(판다스)의 DataFrame의 여러 열에는 서로 다른 종류의 값(숫자, 문자열, 불리언 등)을 담을 수 있습니다. 그리고 행 색인(row indices)과 열 색인(column indices)에 각각 행 이름과 열 이름을 붙일 수도 있죠. 이번 시간에는 데이터를 준비하는 1단계를 알아보겠습니다. 바로 DataFrame을 만들고, DataFrame을 만들기 위해 데이터를 로딩하며, 색인(index)을 관리하는 일입니다. 그럼 Python pandas 사용법, 함께 익혀볼까요?
생성하기(Creating)
pandas의 DataFrame을 만드는 클래스는 pandas.DataFrame
입니다. DataFrame
클래스는 data
, index
, columns
를 매개변수로 갖습니다. 각 매개변수는 순서대로 데이터, 행색인(row index), 열색인(column index)을 의미합니다.
pythonpandas.DataFrame(data, index, columns)
DataFrame은 사전(dictionary), 리스트(list), 배열(array), Series 등 다양한 자료구조로 만들 수 있습니다. 먼저 사전형 자료구조로 DataFrame을 만드는 법부터 알아보겠습니다.
사전
pandas에서 DataFrame을 만들 때 가장 많이 사용하는 자료구조는 리스트를 값으로 가지는 사전입니다.
리스트를 값으로 갖는 사전
리스트를 값으로 갖는 사전이란 사전의 키에 해당하는 값이 리스트인 자료구조를 말합니다. 리스트를 값으로 갖는 사전으로 DataFrame을 만드는 예시 코드는 다음과 같습니다.
pythondata_dict = {'백신': ['아스트라제네카', '화이자', '모더나', '얀센', '노바'],'재고': [100, 200, 300, 400, 500]}df = pd.DataFrame(data_dict,index=[x for x in 'abcde']) # 행색인 지정df

사전을 값으로 갖는 사전
사전을 값으로 갖는 사전이란 사전 안에 사전이 있는 자료구조를 말합니다. 이를 중첩 사전(nested dictionary)이라고 합니다. 중첩된 사전을 입력 데이터로 사용할 때는 바깥에 있는 사전의 키가 열 색인이 되고 안에 있는 키가 행 색인이 됩니다.
pythondata_dict = {'수면시간': {'1번': 7, '2번': 3, '3번': 6},'생산성': {'1번': 8, '2번': 4, '3번': 5}}df = pd.DataFrame(data_dict)df

Series를 값으로 갖는 사전
Series를 값으로 갖는 사전으로 DataFrame을 만들 수도 있습니다. Series를 값으로 갖는 사전을 DataFrame으로 만드는 예시 코드는 다음과 같습니다.
pythondata_dict = {'A조': pd.Series([1, 2, 3, 4, 5],index=[f'{x+1}번' for x in range(5)]),'B조': pd.Series([1, 2, 3, 4, 5],index=[f'{x+1}번' for x in range(5)])}df = pd.DataFrame(data_dict)df

슬라이싱(slicing)으로 가져온 DataFrame의 열로도 DataFrame을 만들 수 있습니다. 슬라이싱은 Python pandas 데이터 확인, 정렬, 선택하는 법에서 자세히 다루겠습니다.
pythondata_selected = {'A': df['A조'][:-1], # 1행부터 마지막 행 전까지'B': df['B조'][:2]} # 1행부터 2행까지df = pd.DataFrame(data_selected)df

배열(array)과 튜플(tuples)을 값으로 갖는 사전도 이와 동일한 방식으로 만들면 됩니다. 지금까지 사전형 자료구조로 DataFrame을 만드는 법을 알아보았습니다. 이번에는 리스트로 DataFrame을 만드는 법을 살펴보겠습니다.
리스트
1개의 1차원 리스트
1차원 리스트로 DataFrame을 만드는 예시 코드는 다음과 같습니다.
pythondata_1dlist = [1, 2, 3, 4, 5] # 1차원 리스트df = pd.DataFrame(data_1dlist, columns=['숫자']) # 열이름 지정df

여러 개의 1차원 리스트
여러 개의 1차원 리스트를 이용해 DataFrame을 만들고 싶다면 zip
함수를 이용하면 됩니다. 이 함수는 한 리스트의 개별 원소를 다른 리스트의 개별 원소와 순서대로 맵핑해줍니다. 여러 개의 1차원 리스트를 이용해 DataFrame을 만드는 예시 코드는 아래와 같습니다.
pythonvegetables = ['사과', '당근', '케일', '토마토', '배추']stocks = [1, 2, 3, 4, 5]ranks = [5, 2, 4, 1, 3]list_of_tuples = list(zip(vegetables, stocks, ranks)) # 튜플로 이루어진 리스트 생성df = pd.DataFrame(list_of_tuples,columns=['상품', '재고', '순위'])df

2차원 리스트
2차원 리스트는 리스트 안에 리스트(list of lists)가 있는 자료 구조를 말합니다. 2차원 리스트로 DataFrame을 만드는 구조는 다음과 같습니다.
pythondata_2dlist = [['사과', 2], ['딸기', 5], ['수박', 1]]df = pd.DataFrame(data_2dlist, columns=['과일명', '수량']) # 열이름 지정df

사전으로 이루어진 리스트
사전을 원소로 갖는 리스트(list of dictionary)는 리스트의 원소가 사전인 자료구조입니다. 사전으로 이루어진 리스트로 DataFrame을 만들면 사전의 키는 열 이름이 되고 값이 각 행에 입력됩니다.
pythondata = [{'개': '멍멍', '고양이': '야옹', '오리': '꽥꽥'},{'개': 5, '고양이': 3, '오리': 4}]df = pd.DataFrame(data)df

만약 기존 데이터에 없는 키를 열 이름으로 지정하면 해당 열에 있는 모든 값은 NaN
이 됩니다.
pythondata = [{'강아지': '멍멍', '고양이': '야옹', '오리': '꽥꽥'},{'강아지': 5, '고양이': 3, '오리': 4}]df = pd.DataFrame(data, index=['1번', '2번'], columns=['강아지', '고양이', '새'])df

배열
Numpy의 배열로 DataFrame을 만드는 방법도 리스트를 이용해서 DataFrame을 만드는 방법과 동일합니다.
pythondata_arr = np.array([[100, 50, 70, 90], [10, 20, 30, 40]])df = pd.DataFrame(data_arr)df

Series
Series로도 DataFrame으로 만들 수 있습니다.
pythondata_ser = pd.Series([1, 2, 3, 4, 5])df = pd.DataFrame(data_ser)df

지금까지 사전, 리스트, 배열, Series 등 다양한 자료구조로 DataFrame을 만드는 법을 알아보았습니다. DataFrame을 직접 만들지 않고 다른 곳에서 가져와서 사용할 수도 있습니다. 파일을 DataFrame 객체 형식으로 읽어오는 것입니다. 이번에는 데이터를 로딩(loading)해서 DataFrame 객체로 읽어오는 방법을 알아보겠습니다. 만든 DataFrame 이나 불러온 DataFrame을 다시 파일로 저장(saving)하는 법도 함께 알아보겠습니다.
로딩하고 저장하기(Loading and Saving)
pandas에서 DataFrame 객체로 읽어올 수 있는 대상은 텍스트 파일, 웹 API, 데이터베이스(database)가 있습니다. 여기서는 텍스트 파일(_.csv, _.xlsx, *.txt 등)을 로딩하고 저장하는 법을 살펴보겠습니다. 웹 API를 이용해서 데이터를 가져오는 방법은 파이썬 웹 크롤링? 웹 스크래핑 개념과 실습 예제를 참조해주세요.
1) CSV 파일: read_csv / to_csv
CSV(Comma-Separated Values)는 쉼표(,)를 구분자(separator)로 갖는 텍스트 파일입니다. pandas에서 CSV 파일을 가져오고 싶을 때는 read_csv
함수를 사용하면 됩니다.
pythondf = pd.read_csv('data.csv') # 읽어올 파일 경로 + 파일명 + 확장자 입력
만약 만든 Series 또는 DataFrame을 CSV 파일 형식으로 저장하고 싶다면 to_csv
함수를 이용하면 됩니다. 특히, 한글로 된 CSV 파일을 저장할 때는 encoding='utf-8-sig'
옵션을 주는 것이 좋습니다. 인코딩을 이 방식으로 하면 한글이 깨지는 현상을 방지할 수 있습니다. 또한, index=False
옵션을 주면 인덱스를 따로 생성하지 않고 저장할 수 있습니다.
pythonpd.to_csv('data.csv', # 저장할 파일 경로 + 파일명 + 확장자 입력encoding='utf-8-sig', # 한글 파일 깨짐 방지index=False) # 인덱스 번호를 따로 생성하지 않기
read_csv
함수 인자에는 50개 이상의 옵션이 있습니다. to_csv
함수 인자에도 20개 이상의 옵션이 있습니다. 모든 옵션은 pandas 공식 홈페이지 pandas.read_csv와 pandas 공식 홈페이지 pandas.to_csv에서 확인하실 수 있습니다. 여기서는 read_csv
의 옵션 중에서 자주 사용하는 옵션만 살펴보겠습니다.
인코딩 설정하기: encoding
앞서 to_csv
의 파라미터에서 살펴보았듯 encoding
옵션은 유니코드(Unicode)의 인코딩 종류를 지정합니다. 한글의 경우 인코딩 방식으로 utf-8-sig
를 지정하면 한글이 깨지는 현상 없이 파일을 잘 불러올 수 있습니다.
pythondf = pd.read_csv('data.csv', encoding='utf-8-sig')
헤더 설정하기: header
header
는 헤더(header)로 사용할 행을 지정하는 옵션입니다. 헤더는 열 이름이 있는 행을 말합니다. header
의 값에는 열이름이 있는 행의 인덱스를 입력하면 됩니다. 예를 들어, 불러오고 싶은 파일에서 컬럼명이 있는 행이 두 번째 행에 있다면 header=1
을 사용하면 됩니다. 만약 파일에 열 이름이 없다면(데이터 레코드로 바로 시작한다면) 옵션에 None
을 전달하면 됩니다. 코드는 다음과 같습니다.
pythondf = pd.read_csv('data.csv', header=0) # 읽어올 CSV 파일에서 컬럼명이 첫 번째 행에 위치함df = pd.read_csv('data.csv', header=None) # 헤더 지정 안하고 데이터 가져오기
만약 첫 번째 행과 두 번째 행을 모두 열색인으로 지정하고 싶다면 header
값으로 열색인으로 만들고 싶은 행의 인덱스가 담긴 리스트를 주면 됩니다.
pythondf = pd.read_csv('data.csv', header=[0, 1]) # 1행과 2행 지정
열 이름 지정하기: names
열의 이름을 지정하고 싶다면 names
옵션을 사용하면 됩니다. 예를 들어 각 열에 순서대로 '가', '나', '다', '라'라는 이름을 붙이고 싶다면, 아래와 같이 names
옵션에 이 값을 담은 리스트를 할당하면 됩니다.
pythondf = pd.read_csv('data.csv', names=['가', '나', '다', '라']) # 열 이름 지정하기
행색인 지정하기: index_col
특정 열을 행색인으로 지정하고 싶다면 index_col
옵션을 사용하면 됩니다. 다음 코드는 '강수량'이라는 이름의 열을 행색인으로 지정합니다.
pythondf = pd.read_csv('data.csv', index_col='강수량') # 행색인으로 사용할 열 지정
만약 계층적 색인(hierarchical index)을 만들고 싶다면 계층적 색인으로 만들고 싶은 열의 인덱스 또는 열 이름이 담긴 리스트를 index_col
옵션에 넘겨주면 됩니다.
pythondf = pd.read_csv('data.csv',index_col=['학교', '학년']) # 계층적 색인 지정: 학교별 학년별 자료
앞에서 행 건너뛰기: skiprows
특정 행을 건너뛰고 자료를 가져오고 싶다면 skiprows
옵션을 사용하면 됩니다. 옵션값으로는 건너뛰고 싶은 행의 개수를 입력하면 됩니다. 예를 들어 1개 행을 건너뛰고 2번째 행부터 데이터를 가져오고 싶다면 skiprows=1
옵션을 사용하면 됩니다(지정된 개수만큼 건너뜀).
pythondf = pd.read_csv('data.csv', skiprows=2) # 2개 행 건너뛰고 3번째 행부터 가져오기
skiprows
옵션은 데이터의 열이름 있는 행이 첫 번째 행에 위치하지 않을 때 사용하면 됩니다. 만약 특정 행을 제외하고 데이터를 불러오고 싶다면 아래와 같이 이 옵션에 건너뛰고 싶은 행의 정수 색인을 담은 리스트를 할당하면 됩니다.
pythondf = pd.read_csv('data.csv', skiprows=[0, 2, 4]) # 0행, 2행, 4행 빼고 데이터 가져오기
뒤에서 행 건너뛰기: skipfooter
skiprows
와는 반대로 skipfooter
는 데이터의 끝부분부터 몇 개의 행을 생략하고 데이터를 불러올 것인지를 지정하는 옵션입니다.
pythondf = pd.read_csv('data.csv', skipfooter=2) # 마지막 행부터 총 2개 행 건너뛰고 데이터 가져옴
가져오고 싶은 행 개수 지정하기: nrows
nrows
는 데이터의 첫 행부터 가져오고 싶은 행의 개수를 지정하는 옵션입니다. 이 옵션을 사용하면 처음부터 몇 번째 행까지 읽어올 것인지를 지정할 수 있습니다.
pythondf = pd.read_csv('data.csv', nrows=3) # 자료가 시작하는 1행부터 총 3개 행 가져오기
다음과 같이 skiprows
와 nrows
을 함께 쓸 수도 있습니다.
pythondf = pd.read_csv('data.csv',skiprows=2 # 처음 2개 행 무시하기nrows=5) # 그 이후부터 5개 행 가져오기
불러오고 싶은 열 지정하기: usecols
자료에서 가져오고 싶은 열을 특정하고 싶다면 usecols
옵션을 사용하면 됩니다. 예제 코드는 다음과 같습니다.
pythondf = pd.read_csv('data.csv', usecols=[0, 1]) # 0번째, 1번째 열만 가져오기df = pd.read_csv('data.csv', usecols=['포켓몬명', '희망전공']) # 2개 열 가져오기
특정 열 1개를 제외하고 데이터를 가져오려면 lambda
함수를 사용하면 됩니다. 예시 코드는 다음과 같습니다.
pythondf = pd.read_csv('data.csv', usecols=lambda x: x !='포켓몬명') # '포켓몬명' 열 제외
만약, 다수의 특정 열을 제외하고 데이터를 가져오고 싶다면 다음과 같은 코드를 사용하면 됩니다.
pythoncolumns_to_skip = ['국어', '수학']df = pd.read_csv('data.csv', usecols=lambda x: x not in columns_to_skip)
결측치 처리하기: na_values
na_values
는 결측치를 처리하는 옵션입니다. 예를 들어, na_values=['없음']
을 사용하면 결측치가 NaN
대신 '없음'으로 표기됩니다.
pythondf = pd.read_csv('data.csv', na_values=['None']) # 결측치가 'None'으로 표기됨
다음으로는 엑셀 파일을 로딩하고 저장하는 법을 알아보겠습니다.
2) 엑셀 파일: read_excel / to_excel
pandas에서 엑셀 파일을 불러오고 싶을 때는 read_excel
함수를 사용합니다.
pythondf = pd.read_excel('data.xlsx') # 읽어올 파일 경로 + 파일명 + 확장자 입력
반면, pandas에서 만든 데이터를 엑셀 파일로 저장하고 싶다면 아래와 같이 to_excel
함수를 사용하면 됩니다.
pythonpd.to_excel('../data/data.xlsx') # 저장할 파일 경로 + 파일명 + 확장자 입력
만일 엑셀 파일 안에 있는 여러 개의 시트 중에서 하나의 시트를 불러오고 싶다면 sheet_name
파라미터에 시트명 또는 시트가 나열된 순서에 해당하는 번호를 입력하면 됩니다. 이때 번호는 0부터 시작합니다.
pythondf = pd.read_excel('data.xlsx', sheet_name='SheetName')# 또는df = pd.read_excel('data.xlsx', sheet_name=1) # 두 번째 시트 불러오기df = pd.read_excel('data.xlsx', sheet_name=[0, 2, 'SheetName']) # 첫 번째, 세 번째, 시트명이 SheetName인 시트 불러오기
엑셀 파일을 로딩할 때는 위에서 살펴본 CSV 파일의 옵션 중에서 encoding
을 제외한 모든 옵션을 사용할 수 있습니다. 특히, 엑셀 파일을 로딩할 때는 불러오고 싶은 특정 구간의 열을 usecols
옵션을 이용해 슬라이싱으로 지정할 수 있습니다.
특정 구간의 열 지정하기: usecols
엑셀 파일을 불러올 때는 usecols
옵션에 슬라이싱을 사용하면 특정 구간의 데이터만 불러올 수 있습니다. usecols
의 슬라이싱 기능은 CSV 파일에서는 작동하지 않습니다. 코드는 다음과 같습니다.
pythondf = pd.read_excel('data.xlsx', usecols='B:D') # B 컬럼부터 D 컬럼까지 가져오기
마지막으로 *.txt 파일을 DataFrame 객체로 불러오는 방법을 알아보겠습니다.
3) *.txt 파일: read_csv(sep=' ' or '\t')
파일 확장자가 _.txt인 파일을 불러올 때는 CSV 파일을 로딩할 때와 마찬가지로 read_csv
함수를 사용하고, 여기에 sep
옵션으로 구분자를 지정하면 됩니다. _.txt 파일은 구분자가 없기 때문에 " " 또는 "\t" 등의 구분자를 넣어주어야 합니다. 예제 코드는 다음과 같습니다.
pythondf = pd.read_csv('data.txt', sep='\t') # 구분자 tab 사용
sep
대신 delimiter
를 사용해도 됩니다. 지금까지 다양한 종류의 텍스트 파일을 DataFrame 객체로 읽어오고, DataFrame을 저장하는 법을 살펴보았습니다. 다음 단계는 색인을 관리하는 작업입니다. 데이터를 선택하고 분석하기 전에 색인을 관리하면 자료를 더 정확하고 효율적으로 분석할 수 있습니다.
색인 관리하기(Managing index)
색인 객체(index objects)란 표(table) 형식으로 이루어진 자료의 각 행과 열에 대해 메타데이터를 저장하는 객체입니다. DataFrame을 만들 때 살펴본 index
와 columns
이 바로 대표적인 색인 객체입니다.
색인 객체는 몇 가지 특징을 지닙니다. 첫째, 인덱스 객체는 배열과 유사하게 고정 크기로 동작합니다. 고정 크기로 동작한다는 의미는 각 값에 할당된 메모리의 크기가 변하지 않고 일정하게 유지된다는 뜻입니다. 둘째, 일단 색인으로 지정한 후에는 색인의 내용을 변경할 수 없습니다. 색인을 변경하고 싶다면 지정한 색인을 해제해야 합니다. 메모리의 크기와 내용이 일정하게 유지되는 점은 색인이 자료구조 사이에서 안전하게 공유되도록 합니다. 따라서, 색인을 잘 다루면 데이터를 분석하는 생산성이 높아집니다.
pandas의 색인은 단층 색인과 다중 색인으로 나뉩니다. 단층 색인은 계층이 1차원인 색인입니다. 다중 색인은 단계(level)가 여러 개 있는 색인을 의미합니다. 다중 색인은 계층적 색인, 멀티인덱스(MultiIndex)라고도 부릅니다. 그럼 색인을 관리하는 도구를 하나씩 살펴보겠습니다.
1) 생성하기: Index
기본 색인
색인은 pandas.Index
클래스로 만들 수 있습니다. 지금까지는 pandas.DataFrame
의 index
매개변수에 행색인으로 사용할 리스트를 넘겨주었다면, 이번에는 색인 객체를 직접 만들어서 index
매개변수에 넘겨주는 것입니다. 다음 코드는 pandas.Index
클래스로 행색인을 만드는 예시 코드입니다.
pythonlabels = pd.Index(['철수네', '영희네']) # Index(['철수네', '영희네'], dtype='object')df = pd.DataFrame(np.arange(8).reshape((2, 4)),index=labels,columns=['전체', '밭1', '밭2', '밭3'])df
계층적 색인
계층적 색인을 만들고 싶다면 pandas.MultiIndex.from_arrays
를 이용하면 됩니다.
pythonindex_arrays = [['A', 'A', 'B', 'B'], [1, 2, 1, 2]]columns = ['X', 'Y']data = [[10, 20], [30, 40], [50, 60], [70, 80]]index = pd.MultiIndex.from_arrays(index_arrays, names=('Letter', 'Number'))df = pd.DataFrame(data, index=index, columns=columns)df
2) 확인하기: index, columns
색인명을 확인하려면 DataFrame.index
와 DataFrame.columns
속성을 이용하면 됩니다. 먼저 행색인을 확인하는 법부터 알아보겠습니다.
행색인: index
행 색인을 알고 싶다면 DataFrame.index
속성을 사용하면 됩니다. 기본 코드는 아래와 같습니다.
pythondf.index# 결과Index(['철수네', '영희네'], dtype='object')
만약 행 색인에 특정 색인이 있는지 확인하려면 다음 코드를 사용하면 됩니다. 이 코드는 특정 색인의 유무를 불리언 값으로 반환해줍니다.
python'포켓몬명' in df.index # False 반환'영희네' in df.index # True 반환
열 색인도 확인해보겠습니다.
열 색인: columns
열 색인을 확인하고 싶다면 DataFrame.columns
속성을 이용하면 됩니다. 기본 코드는 다음과 같습니다.
pythondf.columns# 결과Index(['전체', '밭1', '밭2', '밭3'], dtype='object')
특정 열 이름이 열 색인에 있는지 확인하려면 다음 코드를 사용하시면 됩니다.
python'과' in df.columns # False 반환'밭1' in df.columns # True 반환
파이썬의 집합과는 달리 pandas의 인덱스는 중복되는 값을 허용합니다. 중복되는 색인값을 사용하면 해당 값을 가진 모든 항목이 선택됩니다.
pythonlabels_duplicated = pd.Index(['감자', '감자', '고구마', '미나리'])labels_duplicated# 결과Index(['감자', '감자', '고구마', '미나리'], dtype='object')
만약 중복되는 색인이 있는지 확인하고 싶다면 DataFrame.is_unique
속성을 사용하면 됩니다. is_unique
속성은 행 색인의 값이 유일한지 아닌지를 알려줍니다.
pythondf.index.is_unique # 행 색인 중복 확인df.columns.is_unique # 열 색인 중복 확인# 결과True # 동일한 이름의 행 색인 없음False # 동일한 이름의 열 색인 있음
3) 지정하기: set_index
특정 열을 행 색인으로 설정하려면 DataFrame.set_index
함수를 사용하면 됩니다.
pythondf.set_index('전체') # '전체'라는 이름을 지닌 열을 행 색인으로 지정하기
set_index
함수를 사용해서 얻은 DataFrame은 내부 데이터에 대한 뷰(view) 입니다. 뷰라는 의미는 복사본이 아니라는 뜻입니다. 따라서, 기존의 DataFrame에는 변화가 없습니다. 색인을 지정한 것이 반영되지 않는 것입니다. 만약 DataFrame에 색인으로 지정한 열을 반영하고 싶다면, 기존 DataFrame에 덮어 쓰거나 새로운 DataFrame을 만들거나 inplace
옵션으로 True
값을 전달하면 됩니다.
pythondf_new = df.set_index('전체') # 새로운 DataFrame 만들기# 또는df = df.set_index('전체') # 기존 DataFrame에 덮어쓰기# 또는df.set_index('전체', inplace=True) # 기존 DataFrame에 색인 지정 바로 반영하기
만약 계층적 행 색인을 지정하고 싶다면 set_index
에 계층적 색인으로 지정하고 싶은 리스트를 인자로 전달하면 됩니다.
pythondf5.set_index(['밭1', '밭2'])
계층적 색인으로 만든 열을 기존처럼 열로도 남겨두려면 다음과 같이 drop=False
옵션을 추가하면 됩니다.
pythondf5.set_index(['밭1', '밭2', drop=False]) # 계층적 색인 지정 & 기존처럼 열로도 남기기
4) 정렬하기: sort_index
색인을 정렬하려면 DataFrame.sort_index
함수를 사용하면 됩니다. sort_index
함수는 기본적으로 데이터를 오름차순으로 정렬합니다.
행 색인
pythondf.sort_index()
만약 행 색인을 내림차순으로 정렬하고 싶다면 ascending
옵션에 False 값을 주면 됩니다.
pythondf.sort_index(ascending=False)
열 색인도 정렬해보겠습니다.
열 색인
열 색인을 정렬하고 싶다면 sort_index
함수에 옵션으로 axis=1
을 주면 됩니다. 여기서 1은 열을 의미합니다. 행 색인과 마찬가지로 열 색인도 기본적으로 오름차순으로 정렬됩니다. 코드는 다음과 같습니다.
pythondf.sort_index(axis=1)
열 색인을 내림차순으로 정렬하고 싶다면 행 색인을 내림차순으로 정렬할 때와 마찬가지로 ascending
옵션을 False
값으로 주면 됩니다.
pythondf.sort_index(axis=1, ascending=False)
만약 계층적 색인이 있는 경우에 sort_index
를 사용하려면 level
옵션을 사용할 수 있습니다. level
옵션은 어느 계층을 기준으로 정렬할 것인지를 지정할 수 있습니다. 예제 코드는 아래와 같습니다.
pythondf.sort_index(level=1) # 차상위 계층 정렬
5) 통합 색인명 부여하기: index.name, columns.name
통합 색인명을 지정하고 싶다면 index.name
과 columns.name
속성을 이용하면 됩니다. index.name
통합 행 색인명을 지정하고 columns.name
은 통합 열 색인명을 지정합니다.
행 색인명 지정: index.name
행 색인명을 지정하려면 index.name
속성을 사용하면 됩니다. 다음 코드는 행 색인명을 '구역'으로 지정합니다.
pythondf.index.name = '구역'# 결과Index(['철수네', '영희네'], dtype='object', name='구역') # 행 Index 객체에 name 추가됨
index.name
을 사용하면 통합 행 색인명이 DataFrame에 바로 반영됩니다.
열 색인명 지정: columns.name
통합 열 색인명을 지정하려면 columns.name
속성을 사용하면 됩니다. 기본 코드는 다음과 같습니다.
pythondf.columns.name = '밭'# 결과Index(['전체', '밭1', '밭2', '밭3'], dtype='object', name='밭') # 열 Index 객체에 name 추가됨
지정한 열 색인명은 DataFrame에 바로 반영됩니다.
6) 색인명 변경하기: index.names, columns.names
index.names
행 색인명을 변경하고 싶은 경우에는 DataFrame.index.names
속성을 사용하면 됩니다.
pythondf.index.names = ['소유주'] # 기존 통합 행색인명이 '소유주'로 변경됨
계층적 색인명을 변경하고 싶을 경우에는 변경하고 싶은 행색인명이 담긴 리스트를 해당 속성에 전달하면 됩니다. 예를 들어 계층적 색인이 '포켓몬명'과 '도감번호'인 DataFrame에서 색인명을 변경하고 싶다면 다음 코드를 사용할 수 있습니다.
pythondf.index.names = ['소유주', '번호']
columns.names
열 색인명을 변경하고 싶을 때는 DataFrame.columns.names
속성을 사용하면 됩니다.
pythondf.columns.names = ['식별코드'] # 열 색인이 1개일 때 통합 열 색인명을 '식별코드'로 변경
만약 계층적 색인일 경우에는 아래와 같이 리스트를 사용하면 됩니다.
pythondf.columns.names = ['ID', '번호']
7) 계층 변경하기: swaplevel
DataFrame.swaplevel
함수는 다중 계층에서 계층의 순서를 바꾸고 정렬합니다. 만약 key1
과 key2
의 계층을 서로 바꾸고 싶다면 다음 코드를 사용하면 됩니다.
pythondf.swaplevel('key1', 'key2') # 'key1'과 'key2'의 계층 변경, swaplevel(0, 1)과 동일
만약 계층 순서를 서로 바꾼 뒤 최상위 계층을 기준으로 데이터를 정렬하고 싶다면 다음 코드를 사용할 수 있습니다.
pythondf.swaplevel(0, 1).sort_index(level=0) # 계층 순서 바꾼 뒤 최상위 계층 정렬
8) 재색인하기: reindex, rename, index.map
재색인(reindexing)은 새로운 색인에 맞도록 객체를 새로 생성하는 작업을 의미합니다. 재색인을 하는 방법에는 reindex
속성, rename
함수, index.map
을 이용하는 방법이 있습니다.
reindex
reindex
를 호출하면 데이터를 새로운 색인에 맞게 재배열합니다. 존재하지 않는 색인값이 있다면 NaN
으로 처리됩니다. 예제를 통해 알아보겠습니다.
행 재색인
먼저 행을 재색인해보겠습니다. 예제 코드는 다음과 같습니다.
pythondf.reindex(['짱구네', '영희네'])) # 행 재색인# 결과전체 밭1 밭2 밭3짱구네 NaN NaN NaN NaN영희네 4.0 5.0 6.0 7.0
시계열 같은 순차적인 데이터를 재색인할 때는 값을 보간하거나 채워 넣어야 할 경우가 있습니다. 이때는 method
옵션을 이용해 누락된 값을 채워 넣을 수 있습니다.
pythonobject = pd.Series(['개', '고양이', '토끼'], index=[0, 2, 4])object# 결과0 개2 고양이4 토끼dtype: objectobject.reindex(range(6), method='ffill') # 누락된 값을 직전의 값으로 채워 넣기# 결과0 개1 개2 고양이3 고양이4 토끼5 토끼dtype: object
열 재색인
다음은 열을 재색인하는 코드입니다.
pythoncolumns = ['밭1', '논1', '밭2', '밭4']df.reindex(columns=columns) # 열 재색인# 결과밭1 논1 밭2 밭40 1 NaN 2 NaN1 5 NaN 6 NaN
'밭1'과 '밭2' 색인은 기존에 있었기 때문에 값을 불러왔습니다. 새로 추가된 색인 '논1'과 '밭4'는 불러올 값이 없어 NaN
으로 표시되었습니다.
rename
DataFrame의 행 이름 또는 열 이름을 바꾸고 싶다면 rename
메서드를 사용하면 됩니다.
pythondf.rename(index={'영희네': 'Eun네'}, # 행 색인명 '영희네'를 'Eun네'로 변경columns={'밭1': '논1'}) # 열 색인명 '밭1'을 '논1'로 변경# 결과전체 논1 밭2 밭3철수네 0 1 2 3Eun네 4 5 6 7
아래 예시는 모든 행 색인명과 열 색인명을 한 번에 바꾸는 예제입니다.
pythondf.rename(index=str.title, # 영문으로 된 모든 행 이름의 첫 글자를 대문자로, 나머지는 소문자로 변경columns=str.upper) # 영문으로 된 모든 열 이름을 대문자로 변경
rename
메서드는 원래 객체를 변경하지 않고 새로운 객체를 생성해서 행 또는 열의 이름을 변경해 줍니다. 원본 DataFrame은 보존하고 복사한 DataFrame의 색인명을 바꾸고 싶다면 copy
메서드를 이용하면 됩니다.
pythondf_copy = df.copy()df_copy = df.rename(columns={'밭1':'논1'}) # 기존 변수명인 '밭1'을 새 변수명인 '논1'로 변경
만일, 복사본을 생성하지 않고 원본 DataFrame에 변경 사항을 바로 반영하고 싶다면 inplace=True
옵션을 주면 됩니다.
index.map
index.map
함수를 사용하면 행 색인으로 지정한 값 전부를 변경할 수 있습니다. 이 함수를 사용하면 행 색인의 변경된 값이 DataFrame에 바로 반영됩니다.
pythontransform = lambda x: x[:3].upper()df.index = df.index.map(transform)# 결과Index(['EUN', 'HAN'], dtype='object')
9) 초기화하기: reset_index
reset_index
함수는 set_index
와 반대되는 함수입니다. reset_index
함수는 색인을 초기화합니다. 이 함수는 계층적 색인을 지정했을 때 다시 열 단위의 DataFrame으로 만들어 주는 역할도 합니다.
pythondf.reset_index()df.reset_index(drop=True) # 사용했던 색인을 삭제df.reset_index(drop=True, inplace=True) # 사용했던 색인을 삭제하고 DataFrame에 반영
지금까지 Python pandas 사용법으로 데이터 프레임을 생성하는 법, 데이터를 로딩하고 저장하는 법 그리고 색인을 관리하는 법을 알아보았습니다. 이어지는 시리즈는 Python pandas 데이터 확인, 정렬, 선택하는 법입니다. 여기에서는 DataFrame의 데이터를 확인하고, 정렬 및 선택하는 법을 알아보겠습니다. 모두 수고 많으셨습니다.
참고 문헌
- [1] 웨스 맥키니, 『파이썬 라이브러리를 활용한 데이터 분석』, 김영근, 한빛미디어. 2019, 187-200, 237-246, 283-284, 307-312
- [2] GeeksforGeeks, 「Different ways to create Pandas Dataframe」, GeeksforGeeks, "https://www.geeksforgeeks.org/different-ways-to-create-pandas-dataframe/"
- [3] StackOverflow, 「Pandas usecols all except last」, StackOverflow, "https://stackoverflow.com/questions/33424503/pandas-usecols-all-except-last"