Pandas 알아보기

Pandas란

  • 판다스(Pandas)는 파이썬 데이터 처리를 위한 라이브러리
  • 파이썬을 이용한 데이터 분석과 같은 작업에서 필수 라이브러리로 알려짐
  • 버전은 1.4.2 사용
  • Numpy기반으로 만듬

Pandas 특징

  • 부동 소수점이 아닌 데이터 / 부동 소수점 데이터에서도 결측 데이터(NaN)를 쉽게 처리
  • 크기 변이성 : DataFrame 및 고차원 객체에서 열을 삽입 및 삭제 가능
  • 자동 및 명시적 : 객체를 라벨 집합에 명시적으로 정렬하거나, 사용자가 라벨을 무시하고 Series, DataFrame 등의 계산에서 자동으로 데이터 조정 가능
  • 데이터 세트에서 집계 및 변환을 위한 분할, 적용, 결합 작업을 수행할 수 있는 group-by 함수 제공
  • 누락된 데이터 또는 다른 Python 및 Numpy 데이터 구조에서 서로 다른 인덱싱 데이터를 DataFrame 개체로 쉽게 변환
  • 대용량 데이터 세트의 지능형 라벨 기반 슬라이싱, 고급 인덱싱 및 부분 집합 구하기 가능
  • 직관적인 데이터 세트 병합 및 결합
  • 데이터 세트의 유연한 재구성 및 피벗
  • 축의 계층적 라벨링(눈금당 여러 개의 라벨을 가질 수 있음)
  • 플랫 파일(CSV 및 구분), Excel 파일, 데이터베이스 로딩 및 초고속 HDF5 형식의 데이터 저장/로드에 사용되는 강력한 IO도구
  • 시계열 특정 기능 : 날짜 범위 생성 및 주파수 변환, 무빙 윈도우 통계, 날짜 이동 및 지연

패키지 가져오기

기본적으로 pandas는 pd로 로드합니다.

import pandas as pd
import numpy as np
import pandas as pd

객체 생성

Series 객체

class pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
  • data : array-like, Iterable, dict, scalar value Series에 저장될 데이터
  • index : array-like, index 데이터와 길이가 동일해야 합니다. 데이터가 dict면 key값이 인덱스로 사용
  • dtype : str, numpy.dtype, ExtensionDtype, optional 출력 Series의 데이터 유형입니다. 지정하지 않으면 data 에서 가져옴
  • name : str, optional Series의 이름
  • copy : bool ( defalut False ) 입력 데이터를 복사, Series 또는 1d ndarray 입력에만 영향은 줌
# Series 생성
a = pd.Series([1,3,5, np.nan, 6,8]) # list
s = pd.Series({1 : 'a', 2 : 'b', 3 : 'c'}) # dict
'list',a ,'-'*40,'dict',s

output

('list',
 0    1.0
 1    3.0
 2    5.0
 3    NaN
 4    6.0
 5    8.0
 dtype: float64,
 '----------------------------------------',
 'dict',
 1    a
 2    b
 3    c
 dtype: object)
'a' , a.values, '-'*40,'s' , s.values 
('a',
 array([ 1.,  3.,  5., nan,  6.,  8.]),
 '----------------------------------------',
 's',
 array(['a', 'b', 'c'], dtype=object))
'a' , a.index,'-'*40, 's' , s.index
('a',
 RangeIndex(start=0, stop=6, step=1),
 '----------------------------------------',
 's',
 Int64Index([1, 2, 3], dtype='int64'))

index

# dict의 index 적용 방식
d = {'a' : 1, 'b' : 2, 'c': 3, 1 : 'a', 2 : 'b', 3 : 'c'}
s = pd.Series(data={1 : 'a', 2 : 'b', 3 : 'c'}, index=['a','b','c']) # dict
a = pd.Series(data=d, index=['a','b','c'])
's', s, '-'*40, 'a', a
('s',
 a    NaN
 b    NaN
 c    NaN
 dtype: object,
 '----------------------------------------',
 'a',
 a    1
 b    2
 c    3
 dtype: object)

인덱스는 사전의 key값으로 먼저 빌드됩니다. 이 후 시리즈는 주어진 인덱스 값으로 다시 인덱싱되므로 결과적으로 모든 NaN을 얻습니다.

a[1]
2
a[1:3]
b    2
c    3
dtype: object

copy

# copy는 Series 또는 1d ndarray 입력에만 영향
r = [1,2]
s = pd.Series(r, copy=False)
# s = pd.Series(r, copy=True)
s.iloc[0] = 999
r , '-'*40, s
([1, 2],
 '----------------------------------------',
 0    999
 1      2
 dtype: int64)
r = np.array([1,2])
s = pd.Series(r, copy=False)
# s = pd.Series(r, copy=True)
s.iloc[0] = 999
r , '-'*40, s
(array([999,   2]),
 '----------------------------------------',
 0    999
 1      2
 dtype: int32)

DataFrame 객체

class pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None)
  • data : ndarray, Iterable, dict, DataFrame dict에 인덱스가 정의된 Series가 포함되어 있으면 인덱스에 따라 정렬
  • index : Index, array-like 기본값은 RangeIndex로 설정됨
  • columns : Index, array-like 기본값은 RangeIndex로 설정됨, dict와 같은 데이터일 경우 key값이 사용
  • dtype : dtype ( default None ) 강제할 데이터 유형, 단일 dtype만 허용
  • copy : bool or None ( default None ) 입력에서 데이터를 복사 dict 데이터의 경우 기본값은 Ture DataFrame 또는 2d ndarray 입력의 경우 기본값은 False
dates = pd.date_range("20220519", periods=6)
dates
DatetimeIndex(['2022-05-19', '2022-05-20', '2022-05-21', '2022-05-22',
               '2022-05-23', '2022-05-24'],
              dtype='datetime64[ns]', freq='D')
df = pd.DataFrame(np.random.rand(6, 4), index=dates, columns=list("ABCD"))
df
A B C D
2022-05-19 0.808475 0.890518 0.128044 0.098173
2022-05-20 0.661341 0.678233 0.864386 0.141144
2022-05-21 0.700547 0.812976 0.643775 0.209882
2022-05-22 0.830046 0.173761 0.883834 0.492513
2022-05-23 0.039317 0.212549 0.953871 0.627317
2022-05-24 0.899439 0.478153 0.249467 0.856900
df.index
DatetimeIndex(['2022-05-19', '2022-05-20', '2022-05-21', '2022-05-22',
               '2022-05-23', '2022-05-24'],
              dtype='datetime64[ns]', freq='D')
df.columns
Index(['A', 'B', 'C', 'D'], dtype='object')
# columns 출력
df['A']
2022-05-19    0.808475
2022-05-20    0.661341
2022-05-21    0.700547
2022-05-22    0.830046
2022-05-23    0.039317
2022-05-24    0.899439
Freq: D, Name: A, dtype: float64
# 인덱싱
df[1:3]
A B C D
2022-05-20 0.661341 0.678233 0.864386 0.141144
2022-05-21 0.700547 0.812976 0.643775 0.209882
df2 = pd.DataFrame(
    {
        "A": 1.0,
        "B": pd.Timestamp("20130102"),
        "C": pd.Series(1, index=list(range(4)), dtype="float32"),
        "D": np.array([3] * 4, dtype="int32"),
        "E": pd.Categorical(["test", "train", "test", "train"]),
        "F": "foo",
    }
)

df2
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo

Index 객체

클래스 설명
Index 일반적인 index 객체이며, Numpy 배열 형식으로 축의 이름 표현
Int64Index 정수 값을 위한 Index
MultiIndex 단일 축에 여러 단계 색인을 표현하는 계층적 Index 객체
DatetimeIndex Numpy의 datetime64 타입으로 타임스탬프 저장
PeriodIndex 기간 데이터를 위한 Index
idx = pd.Index([2,4,6,8,10])
idx
Int64Index([2, 4, 6, 8, 10], dtype='int64')

Index 객체 연산

| 연산자 | 메소드 | 설명 | |:—|:—:|:—| | |append|객체를 추가한 새로운 index 반환| ||difference|차집합 반환| |&|intersection|교집합 반환| | \| |union|합집합 반환| | | isin|index가 존재하는지 여부를 boolean 배열로 반환| | | delete|index가 삭제된 새로운 index 반환| | |drop|값이 삭제된 새로운 index 반환| | |insert| index가 추가된 새로운 index 반환 | |is_monotonic| index가 단조성을 가지면 True| | |is_unique| 중복되는 index가 없다면 True| | |unique| index에서 중복되는 요소를 제거하고 유일한 값만 반환|

idx1 = pd.Index([1, 2, 4, 6, 8])
idx2 = pd.Index([2, 4, 6, 8, 10])
print(idx1.append(idx2))
print(idx1.difference(idx2))
print(idx1.intersection(idx2))
print(idx1 & idx2)
print(idx1.union(idx2))
print(idx1 | idx2)
print(idx1.delete(0))
print(idx1.drop(1))
print(idx1 ^ idx2)
Int64Index([1, 2, 4, 6, 8, 2, 4, 6, 8, 10], dtype='int64')
Int64Index([1], dtype='int64')
Int64Index([2, 4, 6, 8], dtype='int64')
Int64Index([2, 4, 6, 8], dtype='int64')
Int64Index([1, 2, 4, 6, 8, 10], dtype='int64')
Int64Index([1, 2, 4, 6, 8, 10], dtype='int64')
Int64Index([2, 4, 6, 8], dtype='int64')
Int64Index([2, 4, 6, 8], dtype='int64')
Int64Index([1, 10], dtype='int64')


C:\Users\ADMINI~1\AppData\Local\Temp/ipykernel_24540/674068743.py:6: FutureWarning: Index.__and__ operating as a set operation is deprecated, in the future this will be a logical operation matching Series.__and__.  Use index.intersection(other) instead
  print(idx1 & idx2)
C:\Users\ADMINI~1\AppData\Local\Temp/ipykernel_24540/674068743.py:8: FutureWarning: Index.__or__ operating as a set operation is deprecated, in the future this will be a logical operation matching Series.__or__.  Use index.union(other) instead
  print(idx1 | idx2)
C:\Users\ADMINI~1\AppData\Local\Temp/ipykernel_24540/674068743.py:11: FutureWarning: Index.__xor__ operating as a set operation is deprecated, in the future this will be a logical operation matching Series.__xor__.  Use index.symmetric_difference(other) instead
  print(idx1 ^ idx2)

인덱싱(Indexing)

reindex : https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.reindex.html

Series 인덱싱

s = pd.Series(['a', 'b', 'c', 'd', 'e'],
             index =[1,3,5,7,9])
s
1    a
3    b
5    c
7    d
9    e
dtype: object
s.iloc[1]
'b'
s.iloc[2:4]
5    c
7    d
dtype: object
s.reindex(range(10))
0    NaN
1      a
2    NaN
3      b
4    NaN
5      c
6    NaN
7      d
8    NaN
9      e
dtype: object
s.reindex(range(10), method='bfill') # bfill NaN을 다음값으로 변경
0    a
1    a
2    b
3    b
4    c
5    c
6    d
7    d
8    e
9    e
dtype: object

DataFrame 인덱싱

df = pd.DataFrame(np.random.randn(6,4), columns=list("ABCD"))
df
A B C D
0 0.872294 1.039292 0.515796 1.703427
1 -0.260745 -0.358807 -0.665951 -0.290013
2 1.344122 -0.090225 -0.163477 1.295620
3 0.116401 0.736589 0.209972 -0.144976
4 -1.369338 -1.019989 -0.674734 -0.807702
5 1.359826 0.947344 -1.451632 -0.629882
df['A']
0    0.872294
1   -0.260745
2    1.344122
3    0.116401
4   -1.369338
5    1.359826
Name: A, dtype: float64
df.A
0    0.872294
1   -0.260745
2    1.344122
3    0.116401
4   -1.369338
5    1.359826
Name: A, dtype: float64
df['E'] = (df.A + df.B)
df.E
0    1.911586
1   -0.619552
2    1.253898
3    0.852990
4   -2.389327
5    2.307170
Name: E, dtype: float64
df.values
array([[ 0.87229448,  1.03929152,  0.51579579,  1.70342731,  1.911586  ],
       [-0.26074461, -0.35880692, -0.66595116, -0.29001319, -0.61955153],
       [ 1.34412241, -0.0902246 , -0.16347724,  1.29562007,  1.25389781],
       [ 0.1164011 ,  0.7365891 ,  0.2099718 , -0.14497633,  0.85299019],
       [-1.36933775, -1.019989  , -0.67473422, -0.80770171, -2.38932675],
       [ 1.3598259 ,  0.94734392, -1.45163242, -0.62988224,  2.30716981]])
# 전치
df.T
0 1 2 3 4 5
A 0.872294 -0.260745 1.344122 0.116401 -1.369338 1.359826
B 1.039292 -0.358807 -0.090225 0.736589 -1.019989 0.947344
C 0.515796 -0.665951 -0.163477 0.209972 -0.674734 -1.451632
D 1.703427 -0.290013 1.295620 -0.144976 -0.807702 -0.629882
E 1.911586 -0.619552 1.253898 0.852990 -2.389327 2.307170
df.loc[:2, :'C']
A B C
0 0.872294 1.039292 0.515796
1 -0.260745 -0.358807 -0.665951
2 1.344122 -0.090225 -0.163477
df.iloc[:3,:3]
A B C
0 0.872294 1.039292 0.515796
1 -0.260745 -0.358807 -0.665951
2 1.344122 -0.090225 -0.163477
#조건
df.loc[(df.E > 0)]
A B C D E
0 0.872294 1.039292 0.515796 1.703427 1.911586
2 1.344122 -0.090225 -0.163477 1.295620 1.253898
3 0.116401 0.736589 0.209972 -0.144976 0.852990
5 1.359826 0.947344 -1.451632 -0.629882 2.307170
df.loc[(df.C < 0) & (df.D > 0)]
A B C D E
2 1.344122 -0.090225 -0.163477 1.29562 1.253898

다중 인덱싱(Multi Indexing)

  • 1차원의 Series와 2차원의 DataFrame 객체, 3차원 이상의 고차원 데이터 처리
  • 단일 인덱스 내에 여러 인덱스를 포함하는 다중 인덱싱

다중 인덱스 Series

df
A B C D E
0 0.872294 1.039292 0.515796 1.703427 1.911586
1 -0.260745 -0.358807 -0.665951 -0.290013 -0.619552
2 1.344122 -0.090225 -0.163477 1.295620 1.253898
3 0.116401 0.736589 0.209972 -0.144976 0.852990
4 -1.369338 -1.019989 -0.674734 -0.807702 -2.389327
5 1.359826 0.947344 -1.451632 -0.629882 2.307170
idx = [(1, 10), (1, 100),
        (2, 10), (2, 100),
        (3, 10), (3, 100),
        (4, 10), (4, 100),
        (5, 10), (5, 100),]
pop = ['ten', 'hun',
       'ten', 'hun',
       'ten', 'hun',
       'ten', 'hun',
       'ten', 'hun',]
s = pd.Series(pop, index=idx)
s
(1, 10)     ten
(1, 100)    hun
(2, 10)     ten
(2, 100)    hun
(3, 10)     ten
(3, 100)    hun
(4, 10)     ten
(4, 100)    hun
(5, 10)     ten
(5, 100)    hun
dtype: object
midx = pd.MultiIndex.from_tuples(idx)
midx
MultiIndex([(1,  10),
            (1, 100),
            (2,  10),
            (2, 100),
            (3,  10),
            (3, 100),
            (4,  10),
            (4, 100),
            (5,  10),
            (5, 100)],
           )
s = s.reindex(midx)
s
1  10     ten
   100    hun
2  10     ten
   100    hun
3  10     ten
   100    hun
4  10     ten
   100    hun
5  10     ten
   100    hun
dtype: object
s[:, 10]
1    ten
2    ten
3    ten
4    ten
5    ten
dtype: object
s[2]
10     ten
100    hun
dtype: object
#unstack() 다중 인덱싱으로 만든 Series를 Data Frame으로 변환
mdf = s.unstack()
mdf
10 100
1 ten hun
2 ten hun
3 ten hun
4 ten hun
5 ten hun
#stack() Data Frame을 다중 인덱싱을 가진 Series로 변환
mdf.stack()
1  10     ten
   100    hun
2  10     ten
   100    hun
3  10     ten
   100    hun
4  10     ten
   100    hun
5  10     ten
   100    hun
dtype: object
t = ['십', '백',
    '십', '백',
    '십', '백',
    '십', '백',
    '십', '백',]
mdf = pd.DataFrame({'영어' : s,
                            '한글' : t})
mdf
영어 한글
1 10 ten
100 hun
2 10 ten
100 hun
3 10 ten
100 hun
4 10 ten
100 hun
5 10 ten
100 hun

다중 인덱스 생성

df = pd.DataFrame(np.random.randn(6,3),
                 index=[['a', 'a', 'b', 'b', 'c', 'c'], [1, 2, 1, 2, 1, 2]],
                 columns=['c1', 'c2', 'c3'])
df
c1 c2 c3
a 1 0.996944 0.395115 -0.913726
2 0.559534 0.408693 -0.878460
b 1 1.170443 -0.842821 -0.332734
2 0.492504 -0.458053 -1.017160
c 1 -0.781801 0.449425 -0.243633
2 1.177329 0.025979 0.593342
# array로 가져오기
pd.MultiIndex.from_arrays([['a','a','b','b','c','c'], [1, 2, 1, 2, 1, 2]])
MultiIndex([('a', 1),
            ('a', 2),
            ('b', 1),
            ('b', 2),
            ('c', 1),
            ('c', 2)],
           )
#곱으로 나타내기
pd.MultiIndex.from_product([['a', 'b', 'c'], [1, 2]])
MultiIndex([('a', 1),
            ('a', 2),
            ('b', 1),
            ('b', 2),
            ('c', 1),
            ('c', 2)],
           )
# 같은 위치로 나타내기
pd.MultiIndex(levels=[['a', 'b', 'c'], [1, 2,]],
             codes=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])
MultiIndex([('a', 1),
            ('a', 2),
            ('b', 1),
            ('b', 2),
            ('c', 1),
            ('c', 2)],
           )
s.index.names = ['숫자', '영어']
s
숫자  영어 
1   10     ten
    100    hun
2   10     ten
    100    hun
3   10     ten
    100    hun
4   10     ten
    100    hun
5   10     ten
    100    hun
dtype: object
idx = pd.MultiIndex.from_product([['a', 'b', 'c'], [1, 2]],
                                 names=['name1', 'name2'])
cols = pd.MultiIndex.from_product([['c1', 'c2', 'c3'], [1, 2]],
                                  names=['col_name1', 'col_name2'])

data = np.round(np.random.randn(6,6), 2)

mdf = pd.DataFrame(data, index=idx, columns=cols)
mdf
col_name1 c1 c2 c3
col_name2 1 2 1 2 1 2
name1 name2
a 1 -0.53 0.64 1.04 0.58 -0.89 -1.00
2 1.23 0.77 -1.17 0.70 -0.54 -0.68
b 1 -1.87 -0.03 0.26 -0.48 -0.93 -1.56
2 0.45 2.95 -0.06 -0.91 -0.37 -0.34
c 1 -1.72 -2.43 -0.48 -0.31 -0.88 -1.08
2 -1.50 1.72 -0.61 1.03 0.80 0.62

인덱싱 및 슬라이싱

mdf
col_name1 c1 c2 c3
col_name2 1 2 1 2 1 2
name1 name2
a 1 -0.53 0.64 1.04 0.58 -0.89 -1.00
2 1.23 0.77 -1.17 0.70 -0.54 -0.68
b 1 -1.87 -0.03 0.26 -0.48 -0.93 -1.56
2 0.45 2.95 -0.06 -0.91 -0.37 -0.34
c 1 -1.72 -2.43 -0.48 -0.31 -0.88 -1.08
2 -1.50 1.72 -0.61 1.03 0.80 0.62
mdf['c2', 1]
name1  name2
a      1        1.04
       2       -1.17
b      1        0.26
       2       -0.06
c      1       -0.48
       2       -0.61
Name: (c2, 1), dtype: float64
mdf.loc[:, ('c2', 1)]
name1  name2
a      1        1.04
       2       -1.17
b      1        0.26
       2       -0.06
c      1       -0.48
       2       -0.61
Name: (c2, 1), dtype: float64
mdf.iloc[:3, :4]
col_name1 c1 c2
col_name2 1 2 1 2
name1 name2
a 1 -0.53 0.64 1.04 0.58
2 1.23 0.77 -1.17 0.70
b 1 -1.87 -0.03 0.26 -0.48
# IndexSlice 이용하기
idx_slice = pd.IndexSlice
mdf.loc[idx_slice[:, 2], idx_slice[:, 2]]
#IndexSlice는 [a,b] 이면 a부터 b까지 b를 포함한다.
col_name1 c1 c2 c3
col_name2 2 2 2
name1 name2
a 2 0.77 0.70 -0.68
b 2 2.95 -0.91 -0.34
c 2 1.72 1.03 0.62
idx_slice[:,2]
(slice(None, None, None), 2)

Categories:

Updated:

Leave a comment