[Pandas] Pandas 개요

Pandas 소개

Pandas 는 구조화된 데이터를 효과적으로 처리하고 저장하는데 사용되는 파이썬 라이브러리로 배열 계산에 특화된 NumPy 를 기반으로 설계되었다.

Pandas 를 이용하면 Series, Dataframe 과 같은 여러 데이터 구조를 생성하고 변경할 수 있으며, 안정적으로 대용량 데이터들을 쉽게 처리할 수 있다. 물론 그 사이즈가 커지면 더욱 복잡한 기술 스택이 요구되기는 한다.

Series

Series(시리즈) 데이터 타입은 NumPy 배열이 보강된 형태로 데이터와 Index 를 가지고 있는 것이 특징이다. 여기서 Index 는 정수형 타입만이 아니라 문자열을 비롯한 다양한 값들로 설정될 수 있다.

예를 들어, 아래와 같이 시리즈 타입 데이터를 만들어 정수가 아닌 문자열로 접근해 값을 불러오는 것을 확인할 수 있다.

import pandas as pd

data = pd.Series(['1FeS', 27, 'abcd@efg.hi', 'xxx-xxxx-xxxx'], index=['name', 'age', 'email', 'phone'])
print(data['name'])

# 1FeS

파이썬을 조금 다뤄본 사용자는 어? 이거 Dictionary 아닌가? 라는 생각이 드는게 당연하다. 그렇다. name 인자로 이름을 지정할 수 있다는 것, 이렇게 지정된 이름 인자는 DataFrame 에서 Column 값으로 변환된다는 것 외에는 크게 다른 점이 없다.

import pandas as pd

data = pd.Series([1, 2, 3, 4], index=['a','b','c','d'], name='sample')
df = pd.DataFrame(data)
print(df)

#    sample
# a       1
# b       2
# c       3
# d       4

data1 = pd.Series([1, 2, 3, 4], index=['a','b','c','d'], name='sample1')
data2 = pd.Series([1, 2, 3, 4], index=['a','b','c','d'], name='sample2')
df = pd.DataFrame([data1, data2])
print(df)

#          a  b  c  d
# sample1  1  2  3  4
# sample2  1  2  3  4

결론적으로 Series 는 딕셔너리 데이터와 매우 유사하며, 한 개의 딕셔너리 데이터는 한 개의 Series 데이터 로 치환할 있다.

import pandas as pd

population_dict= {'korea': 5180,'japan': 12718,'china': 141500,'usa': 32676}
population = pd.Series(population_dict)
print(population)

# korea      5180
# japan     12718
# china    141500
# usa       32676
# dtype: int64

DataFrame

DataFrame(데이터프레임)은 여러 개의 Series 가 모여서 행과 열을 이룬 데이터이다. 핵심은 여러 개의 Series 가 모여서 만들어졌다는 것 이다.

import pandas as pd

population_dict= {'korea': 5180,'japan': 12718,'china': 141500,'usa': 32676}
gdp_dict= {'korea': 169320000,'japan': 516700000,'china': 1409250000,'usa': 2041280000}

population = pd.Series(population_dict)
gdp = pd.Series(gdp_dict)

country = pd.DataFrame({
    'population': population,
    'gdp': gdp
})
print(country)

#        population         gdp
# korea        5180   169320000
# japan       12718   516700000
# china      141500  1409250000
# usa         32676  2041280000

print(country.index)

# Index(['korea', 'japan', 'china', 'usa'], dtype='object')

print(country.columns)

# Index(['population', 'gdp'], dtype='object')

Series 도 NumPy 배열처럼 연산자를 활용할 수 있다. 앞에서 만든 두 Series 를 이용해 1인당 GDP를 구할 수 있다.

gdp_per_capita = country['gdp'] / country['population']
country['gdp per capita'] = gdp_per_capita
print(country)

#        population         gdp  gdp per capita
# korea        5180   169320000    32687.258687
# japan       12718   516700000    40627.457147
# china      141500  1409250000     9959.363958
# usa         32676  2041280000    62470.314604

저장 / 불러오기

만들어낸 DataFrame 은 csv, excel 형태로 저장할 수 있다. 그러나 대부분의 회사 내부 컴퓨터는 DRM 이 걸려있다. 그래서 안타깝게도 파일 저장 과정에서 에러가 발생하거나, 파일을 읽어들이는 도중 에러가 나타날 수 있다.

country.to_csv("./country.csv")
country.to_excel("country.xlsx")

country = pd.read_csv("./country.csv")
country = pd.read_excel("country.xlsx")

Indexing / Slicing

배열과 마찬가지로 DataFrame 데이터에도 Indexing 과 Slicing 이 가능하다. .loc[] 은 명시적인 인덱스를 참조하고, .iloc[] 은 절대적 위치를 사용해 인덱스를 참조한다.

country.loc['korea']
country.iloc[1:3]

새로운 데이터 추가/수정

데이터 추가는 List 형식 또는 딕셔너리 형식으로 가능하다. 데이터 프레임이 가지고있는 컬럼 순서대로 추가하거나, 아예 컬럼들을 딕셔너리의 키 값으로 하여 저장할 수 있다. 데이터 수정은 .loc[index, column] = data 와 같은 형태로 수정할 수 있다.

dataframe= pd.DataFrame(columns=['이름','나이','주소'])
dataframe.loc[0] = ['임원균', '26', '서울’]
dataframe.loc[1] = {'이름':'철수', '나이':'25', '주소':'인천}
dataframe.loc[1, '이름'] = '영희’

누락된 데이터 체크

튜토리얼 데이터와 다르게 현실 데이터는 일부 누락된 경우가 많다. 이런 경우를 확인하기 위해 아래와 같은 메소드를 사용한다.

import pandas as pd

data = pd.DataFrame([1, 2, np.nan, 4], index=['a', 'b', 'c', 'd'], columns=['data'])

print(data.isnull())

#     data
# a  False
# b  False
# c   True
# d  False

print(data.isnotnull())

#     data
# a   True
# b   True
# c  False
# d   True

이렇게 누락된 데이터는 DROP 하거나 FILL 할 수 있다.

print(data.dropna())

#    data
# a   1.0
# b   2.0
# d   4.0

print(data.fillna(0.0))

#    data
# a   1.0
# b   2.0
# c   0.0
# d   4.0

앞서 배웠던 연산들을 사용할 때, 누락된 데이터는 에러를 발생시키는 잠재적 요인이 된다. 아래 예시에서 서로 다른 index 를 가지고 있을 때, 덧셈이 되지 않는 부분이 나타나게 된다.

A = pd.Series([2, 4, 6], index=[0, 1, 2])
B = pd.Series([1, np.nan, 5], index=[1, 2, 3])
A + B

# 0    NaN
# 1    5.0
# 2    NaN
# 3    NaN
# dtype: float64

그러나 누락된 값에 대한 default 값을 정해주어, 계산을 수행할 수 있다.

A = pd.Series([2, 4, 6], index=[0, 1, 2])
B = pd.Series([1, np.nan, 5], index=[1, 2, 3])
A.add(B, fill_value=0)

# 0    2.0
# 1    5.0
# 2    6.0
# 3    5.0
# dtype: float64

DataFrame 정렬

DataFrame 은 sort_values() 를 통해 값으로 정렬할 수 있다.

df= pd.DataFrame({
    'col1': [2, 1, 9, 8, 7, 4],
    'col2': ['A', 'A', 'B', np.nan, 'D', 'C'],
    'col3': [0, 1, 9, 4, 2, 3]
})

print(df.sort_values('col1'))

#    col1 col2  col3
# 1     1    A     1
# 0     2    A     0
# 5     4    C     3
# 4     7    D     2
# 3     8  NaN     4
# 2     9    B     9

print(df.sort_values('col1', ascending=False))

#    col1 col2  col3
# 2     9    B     9
# 3     8  NaN     4
# 4     7    D     2
# 5     4    C     3
# 0     2    A     0
# 1     1    A     1

print(df.sort_values(['col1', 'col2']))

#    col1 col2  col3
# 1     1    A     1
# 0     2    A     0
# 5     4    C     3
# 4     7    D     2
# 3     8  NaN     4
# 2     9    B     9

Updated:

Leave a comment