본문 바로가기

PYTHON-BACK

#파이썬 기초 12일차

728x90

1. Pandas 개요

1-1. Pandas란?

Pandas는 "Panel Data System"과 "Python Data Analysis"에서 이름을 따온 파이썬 라이브러리로, 데이터 분석을 위해 널리 사용됩니다. R의 데이터프레임(Dataframe)과 유사한 형태의 DataFrame 객체를 핵심으로 하며, 엑셀과 유사한 2차원 데이터 구조로 되어 있어 데이터 전처리 및 가공이 용이합니다. 구글, 페이스북 등 데이터를 분석하는 주요 회사의 데이터 과학자들 대부분이 Pandas를 이용하고 있습니다.

1-2. Pandas의 개발 이유

Pandas는 월스트리트의 투자운용회사(헤지펀드) AQR에서 근무하던 웨스 맥키니에 의해 개발되었습니다. 그는 회사에서 사용하는 데이터 핸들링 툴에 만족하지 못해 Pandas를 개발하게 되었습니다.

개발 계기

  • 2008년, 동료가 파이썬으로 간단한 알고리즘을 작성하는 것을 보고 파이썬에 입문하게 되었습니다.
  • 파이썬의 SciPy를 접하면서 상용 통계 도구를 대체하는 오픈소스 도구들이 많음을 발견했습니다.
  • 스탠포드 대학 조나단 테일러 통계학 교수의 오픈소스 패키지에서 관련 모듈을 발견했습니다.
  • 이 오픈소스를 참고하여 R의 DataFrame 객체를 파이썬으로 이식하는 작업에 도전했습니다.
  • 도전 1개월 만에 Pandas 초기 버전을 출시하게 되었습니다(2008년 초).

개발자가 회사에서 사용하던 데이터 분석 도구에서 원했던 기능

  1. 자동적, 명시적으로 축의 이름에 따라 데이터를 정렬할 수 있는 자료구조
  2. 잘못 정렬된 데이터로 인한 일반적인 오류 예방
  3. 다양한 소스에서 가져온 다양한 방식으로 색인된 데이터를 다루는 기능
  4. 통합된 시계열 데이터 처리 기능
  5. 시계열 데이터와 비시계열 데이터를 함께 다룰 수 있는 통합 자료구조
  6. 산술 연산과 한 축의 모든 값을 더하는 등의 데이터 축약 연산은 축의 이름 같은 메타데이터로 전달 가능해야 함
  7. 누락된 데이터를 유연하게 처리할 수 있는 기능
  8. SQL 같은 일반 데이터베이스처럼 데이터를 합치고 관계 연산을 수행하는 기능

 

1-3, Pandas의 대표적인 자료구조 

Series

  • 일련의 객체를 담을 수 있는 1차원 배열 같은 자료구조
  • 어떤 NumPy 자료형이라도 담을 수 있음
  • 배열의 데이터에 연관된 이름을 가진 색인(Index)을 보유

 

DataFrame

  • 표 같은 스프레드시트 형식의 자료구조
  • 여러 개의 칼럼을 가지며 각 칼럼은 서로 다른 종류의 값을 담을 수 있음
  • Row나 Column에 대하여 색인(Index)을 보유

 

Index

  • 표 형식의 데이터에서 각 Row와 Column에 대한 이름과 다른 메타데이터(축의 이름)를 저장하는 객체
  • DataFrame이나 Series 객체에서 사용됨 

Pandas에서는

  • DataFrame과 Series만 알면(특히 DataFrame) 대부분의 애플리케이션에서 사용하기 쉽고 탄탄한 기반을 제공할 수 있음
  • 다른 자료구조도 있긴 있지만 위의 두 가지가 가장 중요함
  • DataFrame은 색인의 모양이 같은 Series 객체를 담고 있는 (파이썬 기본 자료형인)딕셔너리라고 생각하면 편함
import numpy as np
import pandas as pd
from pandas import Series, DataFrame

 

 

2. Pandas 실습 예제

2-1. Series

 
  • Series 객체의 문자열 표현: 왼쪽에 색인, 오른쪽에 해당 색인의 값
  • Series의 배열과 색인 객체는 각각 values와 index 속성으로 얻을 수 있음

 

obj = Series([4, 7, -5, 3])
obj

0    4
1    7
2   -5
3    3
dtype: int64

obj.values

array([ 4,  7, -5,  3])

obj.index

RangeIndex(start=0, stop=4, step=1)

  • 각각의 데이터를 지칭하는 색인을 지정해서 Series 객체를 생성할 때
obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2

d    4
b    7
a   -5
c    3
dtype: int64

  • 위처럼 색인을 원하는 데이터에 할당해서 지정할 수 있다.
obj2.index

Index(['d', 'b', 'a', 'c'], dtype='object')

obj2['b'] # 딕셔너리에서 key사용하는거처럼 쓸 수 있다.

7

 

obj2['d'] = 6 # 인덱스로 접근해 변경가능
print(obj2[['c', 'a', 'd']])

c    3
a   -5
d    6
dtype: int64

 

  • 불리언 배열을 사용해서 값을 걸러내거나 산술 곱셈을 수행하거나 또는 수학 함수를 적용하는 등 NumPy 배열 연산을 수행해도 색인-값은 유지됨
obj2[obj2 > 0]

d    6
b    7
c    3
dtype: int64

obj2 * 2

d    12
b    14
a   -10
c     6
dtype: int64

 

지수함수 계산

np.exp(obj2)

d     403.428793
b    1096.633158
a       0.006738
c      20.085537
dtype: float64

  • Series는 고정길이의 정렬된 딕셔너리라고 생각하면 이해하기 쉬움
'b' in obj2

True

'e' in obj2

False

6 in obj2 # 인덱스에 해당하는 것만 체크되고, 벨류 값은 체크되지 않음

False

6 in obj2.values # .values쓰면 가능함

True 

  • 딕셔너리 객체로부터 Series 객체 생성하기
    • 딕셔너리 객체만으로 Series 객체를 생성하면 Series 객체의 색인은 딕셔너리의 키 값이 순서대로 들어감
    • 시리즈와 딕셔너리 연산들 살펴보기
    • 키를 중심으로 동작됨
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}

obj3 = Series(sdata)
obj3

Ohio      35000
Texas     71000
Oregon    16000
Utah       5000
dtype: int64

states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states)
obj4

California        NaN
Ohio          35000.0
Oregon        16000.0
Texas         71000.0
dtype: float64

  • 누락된 데이터 찾기
pd.isnull(obj4)

California     True
Ohio          False
Oregon        False
Texas         False
dtype: bool

 

pd.notnull(obj4)

California    False
Ohio           True
Oregon         True
Texas          True
dtype: bool

obj4.isnull()

California     True
Ohio          False
Oregon        False
Texas         False
dtype: bool

  • 서로 다르게 색인된 데이터에 대하여 산술 연산 수행하기
  • 어느 하나라도 없으면 전부 배제시킴(NaN은 연산이 안됨)
print(obj3)
print('----------------------------')
print(obj4)
print('----------------------------')
print(obj3 + obj4)

Ohio      35000
Texas     71000
Oregon    16000
Utah       5000
dtype: int64
----------------------------
California        NaN
Ohio          35000.0
Oregon        16000.0
Texas         71000.0
dtype: float64
----------------------------
California         NaN
Ohio           70000.0
Oregon         32000.0
Texas         142000.0
Utah               NaN
dtype: float64

  • Name 속성 사용하기
obj4.name = 'population'
obj4.index.name = 'state'
obj4

state
California        NaN
Ohio          35000.0
Oregon        16000.0
Texas         71000.0
Name: population, dtype: float64

print(obj)
print('----------------------------')
obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
print(obj)

0    4
1    7
2   -5
3    3
dtype: int64
----------------------------
Bob      4
Steve    7
Jeff    -5
Ryan     3
dtype: int64

  • 인덱스는 한번 부여하는 것은 가능한데, 바꾸는 것은 불가능함
  • 잘못만들어진 인덱스를 변경하는방법은 , 전체 인덱싱을 재 인덱싱하는 방법밖에 없다.

2-2. DataFrame

  • DataFrame 생성하기
    • 같은 길이의 리스트에 담긴 딕셔너리 이용
    • NumPy 배열 이용
    • 인덱스를 직접 부여해서 가지고 오기
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002, 2003],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)
frame

pd.DataFrame(data, columns=['year', 'state', 'pop']) # 이런식으로 컬럼을 변경가능함

 

  • row인덱스 부분도 내가 원하는데로 커스텀 가능
  • 자동 부여된 인덱스는 항상 부여되지만 숨어있게됨
frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
                      index=['one', 'two', 'three', 'four',
                             'five', 'six'])
frame2

frame2.columns

Index(['year', 'state', 'pop', 'debt'], dtype='object')

frame2['state']

one        Ohio
two        Ohio
three      Ohio
four     Nevada
five     Nevada
six      Nevada
Name: state, dtype: object

frame2['state']['two']

'Ohio'

frame2.year

one      2000
two      2001
three    2002
four     2001
five     2002
six      2003
Name: year, dtype: int64

frame2.loc['three'] # loc안쓰고 그냥 ['three']는 안됨

year     2002
state    Ohio
pop       3.6
debt      NaN
Name: three, dtype: object

 

  • Column에는 값을 대입할 수 있음
frame2['debt'] = 16.5 #debt에 일괄적용됨
frame2

frame2['debt'] = np.arange(6.) # 연속형의 값도 넣을 수 있다.
frame2

 

  • 리스트나 배열을 Column에 대입할 때
    • 대입하려는 값의 길이가 DataFrame의 크기와 같아야 함 (통째로 집어넣으니까)
    • Series를 대입할 경우, DataFrame의 색인에 따라 값이 대입됨.
    • 없는 색인에는 값이 대입되지 않음 (있는 것에는 넣고 없는 것에는 넣지 않음)
val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
print(val)
print('-------------------------')
frame2['debt'] = val
frame2

two    -1.2
four   -1.5
five   -1.7
dtype: float64
-------------------------

  • 없는 Column을 대입하면 새로운 Column이 생성됨
frame2['eastern'] = frame2.state == 'Ohio'
frame2

del frame2['eastern']
frame2.columns

Index(['year', 'state', 'pop', 'debt'], dtype='object')

 

frame2

 

  • 중첩된 딕셔너리를 이용해서 데이터를 생성할 때, 바깥쪽의 딕셔너리의 키 값이 Column이 되고 안에 있는 키는 Row가 됨
pop = {'Nevada': {2001: 2.4, 2002: 2.9},
       'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = pd.DataFrame(pop)
frame3

 

안쪽이 로우 인덱스, 바깥쪽이 컬럼 인덱스가 됨

 

frame3.T

  • 중첩된 딕셔너리를 이용해서 데이터를 생성할 때, 안쪽의 딕셔너리의 값은 키 값별로 조합되어 결과의 색인이 됨
  • 색인을 직접 지정할 경우, 지정된 색인으로 DataFrame을 생성함
pd.DataFrame(pop, index=[2001, 2002, 2003])

  • Series 객체를 담고 있는 딕셔너리 데이터도 동일하게 처리됨
pdata = {'Ohio': frame3['Ohio'][:-1],
         'Nevada': frame3['Nevada'][:2]}
pd.DataFrame(pdata)

  • DataFrame 생성 시 Index와 Column의 이름을 지정할 수 있음
frame3.index.name = 'year'
frame3.columns.name = 'state'
frame3

  • values 속성은 DataFrame에 저장된 데이터를 2차원 배열로 반환함(Series와 유사)
  • DataFrame의 Column에 서로 다른 dType이 있다면 모든 Column을 수행하기 위해 그 Column 배열의 dType이 선택됨
frame3.values

array([[2.4, 1.7],
       [2.9, 3.6],
       [nan, 1.5]])

frame2.values

array([[2000, 'Ohio', 1.5, nan],
       [2001, 'Ohio', 1.7, -1.2],
       [2002, 'Ohio', 3.6, nan],
       [2001, 'Nevada', 2.4, -1.5],
       [2002, 'Nevada', 2.9, -1.7],
       [2003, 'Nevada', 3.2, nan]], dtype=object)

 

2-3. Index

obj = pd.Series(range(3), index=['a', 'b', 'c'])
obj

a    0
b    1
c    2
dtype: int64

index = obj.index
index

Index(['a', 'b', 'c'], dtype='object')

index[1:]

Index(['b', 'c'], dtype='object')

  • 색인 객체는 변경할 수 없음
  • 따라서 색인 객체는 자료구조 사이에서 안전하게 공유할 수 있음
labels = pd.Index(np.arange(3))
labels

Int64Index([0, 1, 2], dtype='int64')

obj2 = pd.Series([1.5, -2.5, 0], index=labels)
obj2

0    1.5
1   -2.5
2    0.0
dtype: float64

obj2.index is labels

True

frame3

frame3.columns

Index(['Nevada', 'Ohio'], dtype='object', name='state')

'Ohio' in frame3.columns

True

2003 in frame3.index

False

  •  인덱스는 특정 데이터를 가리키는 것이기 때문에 중복 안되고 삭제 x, 판다스에서는 허용함(똑같은 값을 가지면 둘 다 나오게함)
dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar']) 
dup_labels

Index(['foo', 'foo', 'bar', 'bar'], dtype='object')

 

2-4. 기타 주요 기능

  • Series나 DataFrame에 저장된 데이터를 다루는 기본 방법들
 
  • 재색인
  • 인덱스를 하나씩 바꾸는것은 데이터 신뢰도에 문제 생기기에, 전체를 한번에 바꾸는 재색인은 가능하다.
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj

d    4.5
b    7.2
a   -5.3
c    3.6
dtype: float64

obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2

a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64

  • Method 옵션 사용하기
    • 시계열 데이터와 같은 순차적인 데이터를 재색인하고자 할 때, 값을 보간하거나 채워넣어야 할 경우 Method 옵션을 사용하여 해결 가능
    • 재색인 기능의 Method 옵션
      • ffill 또는 pad : 앞의 값으로 채워 넣기
      • bfill 또는 backfill : 뒤의 값으로 채워 넣기
obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3

0      blue
2    purple
4    yellow
dtype: object

obj3.reindex(range(6), method='bfill') # 뒤에 있는것을 집어넣음

0      blue
1    purple
2    purple
3    yellow
4    yellow
5       NaN
dtype: object

 

obj3.reindex(range(6), method='ffill')

0      blue
1      blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object

  • DataFrame에서 색인(Row), Column 또는 둘 다 변경 가능
frame = pd.DataFrame(np.arange(9).reshape((3, 3)),
                     index=['a', 'c', 'd'],
                     columns=['Ohio', 'Texas', 'California'])
frame

 

frame2 = frame.reindex(['a', 'b', 'c', 'd'])
frame2

states = ['Texas', 'Utah', 'California']
frame.reindex(columns=states)

  • 하나의 Row 또는 Column 삭제하기
obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
obj

a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64

new_obj = obj.drop('c')
new_obj

a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

obj

a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64

obj.drop(['d', 'c'])

a    0.0
b    1.0
e    4.0
dtype: float64

obj

a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64

 

data = pd.DataFrame(np.arange(16).reshape((4, 4)),
                    index=['Ohio', 'Colorado', 'Utah', 'New York'],
                    columns=['one', 'two', 'three', 'four'])
data

 

 

data.drop(['Colorado', 'Ohio'])

 

기본 axis는 row로 0. 1은 컬럼

data.drop('two', axis=1)

data.drop(['two', 'four'], axis='columns')

 

obj.drop('c', inplace=True)
obj

a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

 

  • 색인하기, 선택하기, 거르기
obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
obj

 

a    0.0
b    1.0
c    2.0
d    3.0
dtype: float64

print(obj['b'])
print('----------------------')
print(obj[1])
print('----------------------')
print(obj[2:4])
print('----------------------')
print(obj[['b', 'a', 'd']])
print('----------------------')
print(obj[[1, 3]])
print('----------------------')
print(obj[obj < 2])

1.0
----------------------
1.0
----------------------
c    2.0
d    3.0
dtype: float64
----------------------
b    1.0
a    0.0
d    3.0
dtype: float64
----------------------
b    1.0
d    3.0
dtype: float64
----------------------
a    0.0
b    1.0
dtype: float64

  • 라벨명으로 슬라이싱 가능하며 이 때는 시작점과 끝점을 포함한다는 것이 파이썬의 기본 슬라이싱과 다름
print(obj['b':'c'])
print('----------------------')
obj['b':'c'] = 5
obj

b    1.0
c    2.0
dtype: float64
----------------------
a    0.0
b    5.0
c    5.0
d    3.0
dtype: float64

data = pd.DataFrame(np.arange(16).reshape((4, 4)),
                    index=['Ohio', 'Colorado', 'Utah', 'New York'],
                    columns=['one', 'two', 'three', 'four'])
data

 

 

데이터 프레임으로 접근

print(data['two'])
print('----------------------')
print(data[['three', 'one']])

Ohio         1
Colorado     5
Utah         9
New York    13
Name: two, dtype: int64
----------------------
          three  one
Ohio          2    0
Colorado      6    4ㄴ
Utah         10    8
New York     14   12

data

 

 

data[:2]

data[data['three'] > 5]

data < 5

 

data[data < 5] = 0
data

  • 색인의 위치정보를 이용(인덱스가 가지는 위치정보 이용)
data

data.loc['Colorado', ['two', 'three']]

two      5
three    6
Name: Colorado, dtype: int64

 

print(data.iloc[2, [3, 0, 1]])
print('----------------------')
print(data.iloc[2])
print('----------------------')
print(data.iloc[[1, 2], [3, 0, 1]])
print('----------------------')
print(data.loc[:'Utah', 'two'])
print('----------------------')
print(data.iloc[:, :3][data.three > 5])


four    11
one      8
two      9
Name: Utah, dtype: int64
----------------------
one       8
two       9
three    10
four     11
Name: Utah, dtype: int64
----------------------
          four  one  two
Colorado     7    0    5
Utah        11    8    9
----------------------
Ohio        0
Colorado    5
Utah        9
Name: two, dtype: int64
----------------------
          one  two  three
Colorado    0    5      6
Utah        8    9     10
New York   12   13     14

  • 정수 인덱스
ser = pd.Series(np.arange(3.))
ser

0    0.0
1    1.0
2    2.0
dtype: float64

ser2 = pd.Series(np.arange(3.), index=['a', 'b', 'c'])
ser2

a    0.0
b    1.0
c    2.0
dtype: float64

ser2[-1]

2.0

print(ser[:1])
print('----------------------')
print(ser.loc[:1])
print('----------------------')
print(ser.iloc[:1])

0    0.0
dtype: float64
----------------------
0    0.0
1    1.0
dtype: float64
----------------------
0    0.0
dtype: float64

 

  • 산술연산과 데이터 정렬
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
s1

a    7.3
c   -2.5
d    3.4
e    1.5
dtype: float64

s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],
               index=['a', 'c', 'e', 'f', 'g'])
s2

a   -2.1
c    3.6
e   -1.5
f    4.0
g    3.1
dtype: float64

s1 + s2

 

a    5.2
c    1.1
d    NaN # 둘중 하나라도 없음 연산 안됨
e    0.0
f    NaN
g    NaN
dtype: float64

df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'),
                   index=['Ohio', 'Texas', 'Colorado'])
df1

 

df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
                   index=['Utah', 'Ohio', 'Texas', 'Oregon'])
df2

 

df1 + df2

df1 = pd.DataFrame({'A': [1, 2]})
df1

df2 = pd.DataFrame({'B': [3, 4]})
df2

df1 - df2

  • 산술연산 메소드에 채워넣을 값 지정하기
    • 산술연산 메소드: add, sub, div, mul
df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)),
                   columns=list('abcd'))
df1

 

 

df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)),
                   columns=list('abcde'))
df2

df2.loc[1, 'b'] = np.nan
df2

 

df1 + df2

df1.add(df2, fill_value=0)

 

1 / df1

 

df1.rdiv(1)

 

df1.reindex(columns=df2.columns, fill_value=0)

 

  • DataFrame과 Series 간 연산
import numpy as np

arr = np.arange(12.).reshape((3, 4))
arr

array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.]])

arr[0]

array([0., 1., 2., 3.])

arr - arr[0]

array([[0., 0., 0., 0.],
       [4., 4., 4., 4.],
       [8., 8., 8., 8.]])

 

frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
                     columns=list('bde'),
                     index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame

series = frame.iloc[0]
series

 

b    0.0
d    1.0
e    2.0
Name: Utah, dtype: float64

 

frame - series

series2 = pd.Series(range(3), index=['b', 'e', 'f'])
series2

b    0
e    1
f    2
dtype: int64

frame

 

frame + series2

 

series3 = frame['d']
series3

Utah       1.0
Ohio       4.0
Texas      7.0
Oregon    10.0
Name: d, dtype: float64

 

frame.sub(series3, axis='index')

 

  • 함수의 적용과 매핑
frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),
                     index=['Utah', 'Ohio', 'Texas', 'Oregon'])
frame

np.abs(frame)

 

 

람다 함수

f = lambda x: x.max() - x.min()
frame.apply(f)

b    1.142569
d    1.928016
e    1.612983
dtype: float64

frame.apply(f, axis='columns')

Utah      0.686510
Ohio      1.357408
Texas     1.365687
Oregon    0.840383
dtype: float64

 

def f(x):
    return pd.Series([x.min(), x.max()], index=['min', 'max'])

frame.apply(f)

format = lambda x: '%.2f' % x
frame.applymap(format)

frame['e'].map(format)

Utah      -0.27
Ohio       0.38
Texas     -1.15
Oregon     0.47
Name: e, dtype: object

  • 정렬과 순위(랭크)
obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
obj

d    0
a    1
b    2
c    3
dtype: int64

obj.sort_index()

a    1
b    2
c    3
d    0
dtype: int64

frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
                     index=['three', 'one'],
                     columns=['d', 'a', 'b', 'c'])
frame

frame.sort_index()

frame.sort_index(axis=1)

frame.sort_index(axis=1, ascending=False)

obj = pd.Series([4, 7, -3, 2])
obj

0    4
1    7
2   -3
3    2
dtype: int64

obj.sort_values()

2   -3
3    2
0    4
1    7
dtype: int64

obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
obj

0    4.0
1    NaN
2    7.0
3    NaN
4   -3.0
5    2.0
dtype: float64

obj.sort_values()

4   -3.0
5    2.0
0    4.0
2    7.0
1    NaN
3    NaN
dtype: float64

 

frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame

frame.sort_values(by='b')

frame.sort_values(by=['a', 'b'])

obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
obj

 

0    7
1   -5
2    7
3    4
4    2
5    0
6    4
dtype: int64

obj.rank()    # Series와 DataFrame의 rank 메소드는 동점인 항목에 대해서는 평균 순위를 매김

0    6.5
1    1.0
2    6.5
3    4.5
4    3.0
5    2.0
6    4.5
dtype: float64

obj.rank(method='first')    # 데이터 상에서 나타나는 순서에 따라 순위 매기기

 

0    6.0
1    1.0
2    7.0
3    4.0
4    3.0
5    2.0
6    5.0
dtype: float64

obj.rank(ascending=False, method='max')   # 내림차순 순위 매기기

 

0    2.0
1    7.0
2    2.0
3    4.0
4    5.0
5    6.0
6    4.0
dtype: float64

frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1],
                      'c': [-2, 5, 8, -2.5]})
frame

frame.rank(axis='columns')

컬럼 간 순위 (가로로 비교해야함)

  • 중복 색인
obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
obj

 

a    0
a    1
b    2
b    3
c    4
dtype: int64

 

obj.index.is_unique 

False #중복이 들어가 있다는 뜻

 

print(obj['a'])
print('----------------------')
print(obj['c'])

[ ]
print(obj['a'])
print('----------------------')
print(obj['c'])
a    0
a    1
dtype: int64
----------------------
4

 

df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b'])
df

 

 

df.loc['b']

 

 

  • 기술통계 계산과 요약
df = pd.DataFrame([[1.4, np.nan], [7.1, -4.5],
                   [np.nan, np.nan], [0.75, -1.3]],
                  index=['a', 'b', 'c', 'd'],
                  columns=['one', 'two'])
df

df.sum()

one    9.25
two   -5.80
dtype: float64

 

df.sum(axis='columns')

a    1.40
b    2.60
c    0.00
d   -0.55
dtype: float64

df.mean(axis='columns', skipna=False)

a      NaN
b    1.300
c      NaN
d   -0.275
dtype: float64

df.idxmax()

one    b
two    d
dtype: object

df.cumsum()

df

df.describe()

 

 

obj = pd.Series(['a', 'a', 'b', 'c'] * 4) # 반복연산
obj

0     a
1     a
2     b
3     c
4     a
5     a
6     b
7     c
8     a
9     a
10    b
11    c
12    a
13    a
14    b
15    c
dtype: object

 

obj.describe()

count     16
unique     3
top        a
freq       8
dtype: object

 

  • 상관관계와 공분산
# 야후 금융사이트에서 구한 주식 가격
price

volume = pd.read_pickle('https://raw.githubusercontent.com/aidalabs/Lectures/master/LectureFiles/dataset/yahoo_volume.pkl')      # 야후 금융사이트에서 구한 시가 총액
volume

 

 

returns = price.pct_change()      # 각 주식의 퍼센트 변화율
returns

 

returns.head(3)

returns.tail(10)

returns['MSFT'].corr(returns['IBM'])      
# corr 메소드: NA가 아니고 정렬된 색인에서 연속하는 두 Series에 대한 상관관계 계산

0.49976361144151144

returns['MSFT'].cov(returns['IBM'])      
# cov 메소드: NA가 아니고 정렬된 색인에서 연속하는 두 Series에 대한 공분산 계산

8.870655479703546e-05

returns.MSFT.corr(returns.IBM)

0.49976361144151144

 

returns.corr()    # DataFrame의 corr 메소드: DataFrame 행렬상에서의 상관관계

 

returns.cov()    # DataFrame의 cov 메소드: DataFrame 행렬상에서의 공분산

returns.corrwith(returns.IBM)     # DataFrame의 corrwith 메소드: 다른 Series나 DataFrame과의 상관관계 계산. Series를 넘기면 각 Column에 대해 계산한 상관관계를 담고 있는 Series 반환

AAPL    0.386817
GOOG    0.405099
IBM     1.000000
MSFT    0.499764
dtype: float64

returns.corrwith(volume)        # DataFrame의 corrwith 메소드: 다른 Series나 DataFrame과의 상관관계 계산. DataFrame을 넘기면 맞아떨어지는 Column에 대한 상관관계 계산

AAPL   -0.075565
GOOG   -0.007067
IBM    -0.204849
MSFT   -0.092950
dtype: float64

 

  • 유일 값, 값 세기, 멤버십
obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])
obj

0    c
1    a
2    d
3    a
4    a
5    b
6    b
7    c
8    c
dtype: object

obj.value_counts()

c    3
a    3
b    2
d    1
dtype: int64

pd.value_counts(obj.values, sort=False)

c    3
a    3
d    1
b    2
dtype: int64

 

mask = obj.isin(['b', 'c'])
mask

0     True
1    False
2    False
3    False
4    False
5     True
6     True
7     True
8     True
dtype: bool

obj[mask] #True에 해당하는 값만 마스킹함

0    c
5    b
6    b
7    c
8    c
dtype: object

to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a'])
to_match

0    c
1    a
2    b
3    b
4    c
5    a
dtype: object

unique_vals = pd.Series(['c', 'b', 'a'])
unique_vals

 

0    c
1    b
2    a
dtype: object

 

pd.Index(unique_vals).get_indexer(to_match)

array([0, 2, 1, 1, 0, 2])

data = pd.DataFrame({'Qu1': [1, 3, 4, 3, 4],
                     'Qu2': [2, 3, 1, 2, 3],
                     'Qu3': [1, 5, 2, 4, 4]})
data

 

result = data.apply(pd.value_counts).fillna(0)
result

 

  • 누락된 데이터 처리하기
string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
string_data

 

0     aardvark
1    artichoke
2          NaN
3      avocado
dtype: object

string_data.isnull()

0    False
1    False
2     True
3    False
dtype: bool

 

string_data[0] = None
string_data.isnull()

0     True
1    False
2     True
3    False
dtype: bool

data = Series([1, np.nan, 3.5, np.nan, 7])
data

0    1.0
1    NaN
2    3.5
3    NaN
4    7.0
dtype: float64

data.dropna()

0    1.0
2    3.5
4    7.0
dtype: float64

 

data

 

0    1.0
1    NaN
2    3.5
3    NaN
4    7.0
dtype: float64

data[data.notnull()]

0    1.0
2    3.5
4    7.0
dtype: float64

data = DataFrame([[1., 6.5, 3.], [1., np.nan, np.nan],
                  [np.nan, np.nan, np.nan], [np.nan, 6.5, 3.]])
data

cleaned = data.dropna()
cleaned

 

data

 

data.dropna(how='all')      # 모든 값이 NA인 Row 제거

from numpy import nan as NA

 

data[4] = NA
data

data.dropna(axis=1, how='all')

df = DataFrame(np.random.randn(7, 3))
df

 

df.loc[:4, 1] = NA
df

df.loc[:2, 2] = np.nan
df

 

 

df.dropna(thresh=3) # 몇 개 이상의 값이 들어있는 Row만 남기고 나머지는 모두 Drop시키려면, thresh 파라미터에 원하는 개수를 넣는다.

 

df.fillna(0)

df.fillna({1: 0.5, 2: -1})

_ = df.fillna(0, inplace=True)
df

df = DataFrame(np.random.randn(6, 3))
df

df.loc[2:, 1] = np.nan
df

df.loc[4:, 2] = np.nan
df

df.fillna(method='ffill')

df.fillna(method='ffill', limit=2)

data = Series([1., np.nan, 3.5, np.nan, 7])
data

0    1.0
1    NaN
2    3.5
3    NaN
4    7.0
dtype: float64

data.fillna(data.mean())

0    1.000000
1    3.833333
2    3.500000
3    3.833333
4    7.000000
dtype: float64

728x90

'PYTHON-BACK' 카테고리의 다른 글

#파이썬 기초 14일차  (0) 2024.07.18
#파이썬 기초 13일차  (0) 2024.07.17
#파이썬 기초 11일차  (0) 2024.07.11
#파이썬 기초 10일차_2  (0) 2024.07.10
#파이썬 기초 10일차_1  (0) 2024.07.10