DATA ANALYSIS/TIL

[Day19] 데이터 핸들링(2)

yel1nk 2023. 5. 24. 02:30

Numpy

난수 생성 함수 - Random

np.random.rand(2, 2) # 0 ~ 1 사이 값 랜덤 
np.random.randn(2, 2) # 평균=0, 분산=1 : 표준 정규 분포
np.random.randint(0, 10, size=(2, 2)) # 랜덤한 정수값 생성 (0~9)
a = np.arange(5)
np.random.shuffle(a) # 복사본 생성 x -> 원본 값이 변경됨 
np.random.choice(a, 3, replace=False) # 중복 허용 x
np.random.choice(a, 3, p=[0.1, 0.3, 0.2, 0.3, 0.1]) # p값을 100%(1)로 설정
# permutation 순열 : 서로 다른 n개의 원소에서 r개를 중복없이 순서에 상관있게 선택 혹은 나열하는 것
np.random.permutation(a) # 원본 값 유지
# 정규분포를 따르는 난수 생성
# np.random.normal('평균', '표준편차', '갯수')
np.random.normal(0, 1, 3)  # == np.random.randn(3)

Pandas

import pandas as pd

기능

  1. 데이터 로딩 및 저장
  2. 데이터 인덱싱 및 슬라이싱
  3. 결측치 처리
  4. 데이터 변환
  5. 데이터 집계 및 그룹화
  6. 시계열 데이터
  7. 데이터 시각화

구조

  1. Series (시리즈)
  2. DataFrame (데이터프레임)

Series

# List로 생성하기 
s = pd.Series([1, 2, 3, 4])

# Dictionary로 생성하기 
s2 = pd.Series({'a': 1, 'b': 2, 'c': 3, 'd': 4})

# Scalar 값으로 생성하기 
s3 = pd.Series(5, index=[0, 1, 2])

인덱싱 / 슬라이싱

명시적 인덱스(Explicit Index) : 사용자가 직접 지정한 인덱스

  • 인덱스를 임의로 설정할 수 있으며, 이를 통해 데이터를 쉽게 조회할 수 있습니다.

묵시적 인덱스(Implicit Index) : 판다스가 자동으로 생성하는 인덱스

  • 0부터 시작하는 정수형 인덱스로, 데이터프레임과 시리즈를 생성할 때 index 속성을 설정하지 않으면 자동으로 생성됩니다.
data = [1, 2, 3, 4, 5]
index = ['a', 'b', 'c', 'd', 'e']
series = pd.Series(data, index=index) # 명시적 인덱스
series = pd.Series(data) # 묵시적 인덱스
print(series[0])
# 1

print(series[0:3])
# 0    1
# 1    2
# 2    3
# dtype: int64

print(series[::-1]) # 역순 
# 4    5
# 3    4
# 2    3
# 1    2
# 0    1
# dtype: int64

Boolean Indexing

print(series > 2)  
# 0    False
# 1    False
# 2     True
# 3     True
# 4     True
# dtype: bool

print(series[series > 2]) # a[a 조건]
# 2    3
# 3    4
# 4    5
# dtype: int64

산술 연산

print(series + 100)
print(series - 100)
print(series * 100) # 곱 
print(series ** 100) # 제곱 
print(series / 100) # 몫 (float)
print(series % 100) # 나머지 
print(series // 100) # 몫 (int)

객체 접근

  • keys -> index
  • values
  • items
series = pd.Series([1, 2, 3, 4, 5])

print(series.keys())
print(series.index)
# RangeIndex(start=0, stop=5, step=1)  # RangeIndex : Pandas에서 자동으로 인덱스를 생성해준 것 

print(series.values)
# [1 2 3 4 5]
s2 = pd.Series({'a': 1, 'b': 2, 'c': 3, 'd': 4})

print(s2.keys()) 
print(s2.index)
# Index(['a', 'b', 'c', 'd'], dtype='object')

print(s2.items()) # zip : 순회 가능한 쌍 
# <zip object at 0x7fb0b43adb40>

for index, value in s2.items():
    print(f'인덱스: {index}, 데이터: {value}')
# 인덱스: a, 데이터: 1
# 인덱스: b, 데이터: 2
# 인덱스: c, 데이터: 3
# 인덱스: d, 데이터: 4
s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])

# loc : 행에 접근 
print(s.loc['a'])
print(s['a']) 
# 10
print(s.loc['b':'d']) # 레이블 지정 -> 'd' 포함 
print(s['b':'d'])
# b    20
# c    30
# d    40
# dtype: int64

# iloc :(행에 기반한) 열에 접근
print(s.iloc[1])
# 20
print(s.iloc[1:3]) # 일반 슬라이싱과 동일 -> 3 미포함 
# b    20
# c    30
# dtype: int64

위의 코드에서 s['b':'d']s.loc['b':'d'] 모두 'b'부터 'd'까지의 값을 선택하여 동일한 결과를 반환합니다.

이러한 이유는 pandas가 일반적인 경우에는 인덱스 레이블을 기반으로 슬라이싱을 수행하기 때문입니다. 따라서, 일반적인 정수 인덱스가 아닌 인덱스 레이블을 가진 경우에도 s['b':'d']를 사용하여 슬라이싱을 수행할 수 있습니다.

하지만 차이점은 존재합니다. loc을 사용하면 인덱스 레이블을 명시적으로 사용하여 데이터에 접근하는 것이므로, 인덱스 레이블의 타입에 따라 조금 다른 동작을 할 수 있습니다. 또한, loc을 사용하여 단일 인덱스 레이블을 선택하는 것과 슬라이싱을 통해 데이터에 접근하는 것은 일관성을 유지하기 위해 구문적으로 구분될 수 있습니다.

따라서, s['b':'d']s.loc['b':'d']는 대부분의 경우 동일한 결과를 제공하지만, loc은 더 많은 유연성을 제공하고 명시적인 인덱스 레이블 기반의 데이터 접근 방법을 제공합니다.

# at : loc 과 비슷, 하나의 값만 가져올 때
print(s.at['a'])
# 10

# iat : iloc 과 비슷 
print(s.iat[1])
# 20
# get : 없는 값에 대한 처리 방식 다름 -> error 대신 default
print(s.get('e', default=-1))
# -1

결측값 (Nan, None)

  • Nan(Not a Number) -> float
  • None -> none
    • isna() = isnull()
    • notna() = notnull()
      • sum() 으로 카운팅
    • dropna()
    • fillna(num)
data = [1, 2, 3, None] # list

print(np.array(data)) # None - 수치연산 시 error
# [1 2 3 None]

print(pd.Series(data)) # NaN - 수치연산 처리가 용이
# 0    1.0
# 1    2.0
# 2    3.0
# 3    NaN
# dtype: float64
s = pd.Series([1, 2, 3, None])

print(s.isna())
print(s.isnull())
# 0    False
# 1    False
# 2    False
# 3     True
# dtype: bool

print(s.isna().sum()) # True 값 카운팅 
print(s.isnull().sum())
# 1

print(s.notnull())
# 0     True
# 1     True
# 2     True
# 3    False
# dtype: bool
# 결측치 제거
print(s.dropna())

# 결측치를 0으로 치환 
print(s.fillna(0))

집계 함수

s = pd.Series([1, 3, 5, 7, 9])

print(s.count()) # 카운트 함수 
print(s.min()) # 최소값
print(s.max()) # 최대값 

print(s.mean()) # 평균 
print(s.median()) # 중앙값  
print(s.std()) # 표준편차 
print(s.var()) # 분산
print(s.describe()) # 기초 통계를 한 번에 볼 수 있는 함수
# count    5.000000
# mean     5.000000
# std      3.162278
# min      1.000000
# 25%      3.000000
# 50%      5.000000
# 75%      7.000000
# max      9.000000
# dtype: float64

'DATA ANALYSIS > TIL' 카테고리의 다른 글

[Day21] 데이터 핸들링(4)  (0) 2023.05.25
[Day20] 데이터 핸들링(3)  (0) 2023.05.24
[Day18] 데이터 핸들링(1)  (0) 2023.05.23
[Day 17] Python 심화(7)  (0) 2023.05.18
[Day15] Python 심화(6)  (0) 2023.05.17