260106 [ Day 6 ] - Python (3), NumPy (1), Pandas (1)

TaeHyun·2026년 1월 6일

TIL

목록 보기
129/184

시작하며

오늘은 어제까지 배웠던 내용 중 중요한 내용을 다시 정리한 뒤, 객체 복사에 대한 개념을 배웠다. 그 뒤 NumPy와 Pandas에 대해 공부했다.

단순 자료형

정수 (int)

  • 소수점이 없는 수

실수 (float)

  • 소수점이 있는 수

문자열 (str)

  • 여러 문자, 숫자, 기호 등의 시퀀스를 따옴표로 감싼 것

단순 자료형 변환

  • 소수점이 있는 문자열을 정수로 변환하려고 하면 에러 발생

부울 (bool)

  • True 또는 False로 표현하는 자료형
  • 값 또는 원소가 있으면 True, 없으면 False

복합 자료형

리스트

  • 대괄호 안에 원소를 나열한 복합 자료형
  • 다양한 자료형의 원소를 가질 수 있음
    • 수, 문자열, 리스트, 튜플, 딕셔너리 등 다양한 객체 가능
  • 원소의 입력 순서를 유지하며 원소의 중복을 허용
  • 원소에 인덱스가 있으므로 인덱싱 / 슬라이싱 가능
  • mutable list 이므로 원소를 추가, 삭제 또는 변경 가능

리스트 주요 메서드

  • append(x) : x를 리스트 마지막에 추가
  • remove(x) : x를 삭제
  • sort() : 오름차순 정렬, 자료형이 섞여 있으면 에러 발생

튜플

  • immutable list 이므로 원소를 추가, 삭제 또는 변경할 수 없음

집합

  • 집합의 원소는 해시(검색) 가능하고 변하지 않아야 한다는 특징이 있음
  • 생성 시 중복 원소를 제거하고 오름차순 정렬(수치형)
    • 데이터 정합성 확인(고유값)
    • 조인하기전 활용

딕셔너리

  • 중괄호를 열고 원소(키: 값)를 콤마로 나열
    • 키에 수와 문자열, 값에 다양한 자료형(수, 시퀀스, 딕셔너리 등)을 지정
    • dict 클래스로 딕셔너리를 생성할 때는 키와 값을 등호로 연결(키는 문자열만 가능)
  • 원소의 입력 순서를 유지(Python 3.7 이후)하고 키의 중복을 허용하지 않음
    • 같은 키에 서로 다른 값을 할당하면 마지막에 할당한 값으로 업데이트
  • 인덱스가 없으므로 대괄호 안에 키를 지정하여 접근(원소명)

딕셔너리 주요 메서드

  • items() : 딕셔너리의 모든 키와 값을 튜플로 묶어서 반환
  • keys() : 딕셔너리의 모든 키를 반환
  • values() : 딕셔너리의 모든 값을 반환

조건문

if 조건문 기본 구조

  • if 조건문에 지정하는 조건 코드는 실행 결과로 True 또는 False를 스칼라로 반환해야 함

삼항 연산자

  • 조건에 따라 값을 선택할 수 있는 표현식
  • 값1 if 조건1 else 값2
'합격' if scores[0] >= 90 else '재검사'

# else 뒤에 새로운 조건 사용 가능
'합격' if scores[0] >= 90 else '재검사' if scores[0] >= 80 else '불합격'

for 반복문

for문 기본 구조

  • for문은 반복 실행할 범위가 정해져 있을 때 사용

리스트 컴프리헨션

  • 기본 형태
[i ** 2 for i in nums]
  • 조건 추가
[i ** 2 for i in nums if i % 2 == 0]
  • 삼항 연산자 추가
[i ** 2 if i % 2 == 0 else i * 2 for i in nums]

while 반복문

  • 조건을 만족하는 동안 계속 반복 실행해야 할 때 사용
    • 실행 도충 break를 만나면 중단

사용자 정의 함수

사용자 정의 함수의 기본 구조

  • 매개변수에 인수를 전달받아 실행한 값을 반환
  • 함수를 정의할 때 괄호 안에 나열한 것을 매개변수(parameter)라고 함
  • 함수를 실행할 때 매개변수에 등호로 전달하는 값을 인수(argument)라고 함
  • 함수 내에서 사용하는 변수는 지역 변수라고 함
  • 함수 실행 도중 return을 만나면 즉시 종료하며, return문을 생략하면 None을 반환
    • return문 오른쪽에 여러 값을 콤마로 나열하면 튜플 형태로 반환

lambda 표현식

  • 함수처럼 동작하는 일회성 한 줄 코드에 적합
  • () 로 사용하거나 변수에 할당하여 사용 가능
(lambda hgt, wgt: wgt / (hgt / 100) ** 2)(175, 70)

bmi2 = lambda hgt, wgt: wgt / (hgt / 100) ** 2
bmi2(175, 70)

객체 복사

참조 바인딩

  • 참조 : 변수가 객체를 가리키는 것
  • 참조 바인딩 : 두 변수가 같은 객체를 참조하는 것
    • 완전히 동일한 메모지 주소를 공유
  • 참조 바인딩은 원본을 유지할 수 없음
a = [[1, 2], [3, 4]]
b = a
  • 두 변수가 가리키는 메모리 주소가 같음
print(id(a)) # 2758672173056
print(id(b)) # 2758672173056
print(id(a) == id(b)) # True
  • b의 원소를 변경하면 a도 변경
b[0] = 9

print(b) # [9, [3, 4]]
print(a) # [9, [3, 4]]

얕은 복사

  • 새로운 객체 생성, 하지만 내부 요소는 원본 참조 공유
a = [[1, 2], [3, 4]]
b = a.copy()
  • 두 변수가 가리키는 메모리 주소가 다름
print(id(a)) # 2758666124160
print(id(b)) # 2758672176640
print(id(a) == id(b)) # False
  • 두 변수의 첫 번째 원소가 가리키는 메모리 주소는 같음
print(id(a[0])) # 2758672165568
print(id(b[0])) # 2758672165568
print(id(a[0]) == id(b[0])) # True
  • b의 첫 번째 원소를 변경하면 b만 변경
b[0] = 99
print(b) # [99, [3, 4]]
print(a) # [[9, 2], [3, 4]]
  • 내부 원소는 원본 참조
b[1][0] = 9
print(b) # [99, [9, 4]]
print(a) # [[9, 2], [9, 4]]

참조 반복

  • 컨테이너를 새로 만들지만, 내부 구조를 그대로 유지한 상태로 반복
a = [[1, 2], [3, 4]]
b = a * 2
print(a) # [[1, 2], [3, 4]]
print(b) # [[1, 2], [3, 4], [1, 2], [3, 4]]
b[0][0] = 9

print(a) # [[9, 2], [3, 4]]
print(b) # [[9, 2], [3, 4], [9, 2], [3, 4]]

깊은 복사

  • 리스트를 새로 만들고, 내부 구조도 재귀적으로 새로 만듬
    • import copy : 파이썬 표준 라이브러리
  • 두 변수가 가리키는 메모리 주소가 다름
print(id(a)) # 2758672196096
print(id(b)) # 2758672180736
print(id(a) == id(b)) # False
  • 두 변수의 첫 번째 원소가 가리키는 메모리 주소도 다름
print(id(a[0])) # 2758672775936
print(id(b[0])) # 2758672062464
print(id(a[0]) == id(b[0])) # False
  • b의 첫 번째 원소를 변경하면 b만 변경됨
b[0][0] = 9
print(b) # [[9, 2], [3, 4]]
print(a) # [[1, 2], [3, 4]]

NumPy 기초

NumPy

  • 0~n 차원의 배열(ndarray)을 생성(0차원은 스칼라)
  • 배열의 차원(dimension)을 확인하고 형태(shape)를 변경
  • 1차원 배열(벡터) 또는 2차원 배열(행렬) 연산을 실행(선형대수)

배열 확인

  • array.ndim : 배열의 차원 반환
  • array.shape : axis 축에 따른 원소 개수를 튜플로 반환
  • array.size : 전체 원소 개수를 정수로 반환
  • array.dtype : 원소의 자료형을 반환

0차원 배열 생성

a = 1

ar0 = np.array(a)

a # 1
ar0 # array(1)
type(ar0) # numpy.ndarray
ar0.ndim # 0
ar0.shape # ()
ar0.size # 1
ar0.dtype # dtype('int64')

1차원 배열

배열 생성

  • 배열은 원소 자료형을 통일 시킴
    • 정수 → 실수 → 문자열
ar1 = np.array(li1)
ar1 
# li1 = [1, 2, 3] # array([1, 2, 3])
# li1 = [1, 2.0, 3] # array([1., 2., 3.])
# li1 = [1, 2.0, '3'] # array(['1', '2.0', '3'], dtype='<U32')
type(ar1) # numpy.ndarray
ar1.ndim # 1
ar1.shape # (3,)
ar1.size # 3
ar1.dtype # dtype('<U32')

자료형 변환 (astype)

  • 문자열 실수 → 정수 = 에러 발생
ar1.astype(int)
# ValueError: invalid literal for int() with base 10: np.str_('2.0')
  • 메서드 체이닝 사용
ar1.astype(float).astype(int).astype(str).astype(int)
# array([1, 2, 3])

자료형 지정

np.array(li1, dtype=int) # array([1, 2, 3])
np.array(li1, dtype=float) # array([1., 2., 3.])
np.array(li1, dtype=str) # array(['1', '2.0', '3'], dtype='<U3')
  • 앞에있는 object는 np.array 클래스에 정의된 매개변수이고, 뒤에 있는 object는 파이썬 내장 함수
    • object 타입은 원본 그대로의 자료형으로 지정
np.array(object=li1, dtype=object) # array([1, 2.0, '3'], dtype=object)

Pandas 시리즈를 생성할 때 원소에 문자열을 포함하면 시리즈의 원소 자료형을 object로 자동 변환

시리즈의 자료형이 object일 대 문자열과 수치형 원소가 섞여 있을 수 있음

간격이 일정한 배열 생성 (np.arange / np.linspace)

  • np.arange() : 시작 이상 끝 미만의 정수 배열을 지정한 간격으로 생성
np.arange(6) # array([0, 1, 2, 3, 4, 5])
np.arange(1, 6) # array([1, 2, 3, 4, 5])
np.arange(1, 6, 2) # array([1, 3, 5])
np.arange(0, 1, 0.1) # array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
np.arange(0, 1.1, 0.1) # array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
  • np.linspace() : 시작부터 끝까지 균일 간격으로 지정한 개수만큼 숫자를 생성 (float)
np.linspace(0, 1, 10+1) # array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])

원소를 반복한 배열 생성 (np.tile / np.repeat)

np.tile(ar1, 2)
# array(['1', '2.0', '3', '1', '2.0', '3'], dtype='<U32')

np.repeat(ar1, 2)
# array(['1', '1', '2.0', '2.0', '3', '3'], dtype='<U32')

np.repeat(ar1, [3, 2, 1])
# array(['1', '1', '1', '2.0', '2.0', '3'], dtype='<U32')

기본 인덱싱

ar1 = np.arange(1, 12, 2)
ar1 # array([ 1,  3,  5,  7,  9, 11])

ar1[0] # np.int64(1)
ar1[1] # np.int64(3)
ar1[-1] # np.int64(11)
  • 넘파이 버전 2부터 np.int64(n) 형태로 바뀜
    • 값만 보고 싶다면 마지막에 item 메서드를 추가
ar1[0].item() # 1

type(ar1[0]) # numpy.int64
type(ar1[0].item()) # int

슬라이싱

ar1[0:3] # array([1, 3, 5])
ar1[:3] # array([1, 3, 5])
ar1[3:] # array([ 7,  9, 11])
ar1[:] # array([ 1,  3,  5,  7,  9, 11])

고급 인덱싱(팬시 인덱싱, 불리언 인덱싱)

  • 팬시 인덱싱 : 정수 배열을 사용하여 여러 인덱스로 여러 요소를 한번에 선택
ar1[[3, 1, 2]] # array([7, 3, 5])
ar1[[3, 3, 3]] # array([7, 7, 7])
ar1[[3, 1, 2, 0, 4, 5]] # array([ 7,  3,  5,  1,  9, 11])
ar1[[3, 1, 2, 0, 4, 5, 3, 1, 2, 0, 4, 5]] 
# array([ 7,  3,  5,  1,  9, 11,  7,  3,  5,  1,  9, 11])
  • 불리언 인덱싱 : 원본 배열의 원소 개수와 같지 않으면 에러 발생
ar1[[False, False, False, True, True, True]] # array([ 7,  9, 11])

브로드캐스팅

  • 왼쪽 배열 원소 개수만큼 오른쪽 연산자를 확장시켜 원소마다 비교 연산을 수행
    • 두 배열의 차원을 뒤(낮은 차원)에서부터 비교
    • 크기가 같거나 한쪽이 1인 경우 확장이 가능
ar1[ar1 >= 7] # array([ 7,  9, 11])

2차원 배열

배열 생성

li2 = [[1, 3, 5], [7, 9, 11]]
ar2 = np.array(li2)

ar2
# array([[ 1,  3,  5],
#        [ 7,  9, 11]])
type(ar2) # numpy.ndarray
ar2.ndim # 2
ar2.shape # (2, 3)
ar2.size # 6
ar2.dtype # dtype('int64')

배열의 재구조화 (reshape, flatten)

  • reshape() : 1차원 배열을 2차원 배열로 변환
    • 원소의 개수가 같아야 재구조 가능
ar1.reshape(2, 3)
# array([[ 1,  3,  5],
#        [ 7,  9, 11]])

# order 속성 변경
ar1.reshape(2, 3, order='F')
# array([[ 1,  5,  9],
#        [ 3,  7, 11]])
  • -1 입력시 자동으로 계산
ar2 = ar1.reshape(2, -1)
ar2
# array([[ 1,  3,  5],
#        [ 7,  9, 11]])

ar2 = ar1.reshape(-1, 3)
ar2
# array([[ 1,  3,  5],
#        [ 7,  9, 11]])
  • flatten() : 2차원 배열을 1차원 배열로 변환
    • 항상 새로운 배열을 만들기 때문에 원본은 변화 X
  • ravel()
    • 원본 메모리를 그대로 사용하기 때문에 빠르게 동작, 원본 변화 O
ar2.flatten()
# array([ 1,  3,  5,  7,  9, 11])

ar2.ravel()
# array([ 1,  3,  5,  7,  9, 11])

인덱싱 및 슬라이싱

ar2
# array([[ 1,  3,  5],
#        [ 7,  9, 11]])
  • 인덱싱
ar2[0, 0] # np.int64(1)
ar2[0] # array([1, 3, 5])
ar2[:, 0] # array([1, 7])
  • 슬라이싱
ar2[0:2, 0:2]
# array([[1, 3],
#        [7, 9]])
ar2[:, 1:3]
# array([[ 3,  5],
#        [ 9, 11]])
ar2[:, [2, 1]]
# array([[ 5,  3],
#        [11,  9]])

산술 연산

ar1 = np.array([[0, 1, 2]])
ar1 # array([[0, 1, 2]])

ar1 + 1 # array([[1, 2, 3]])
ar2 = ar1.reshape(-1, 1)
ar2
# array([[0],
#        [1],
#        [2]])

ar2 * 2
# array([[0],
#        [2],
#        [4]])

수학 관련 속성 및 함수

구분상세 내용구분상세 내용구분상세 내용
np.e자연상수(2.718…)np.sqrt()제곱근np.mean()평균
np.pi파이(3.14…)np.power()거듭제곱np.median()중위수
np.nan결측값(float)np.exp()자연상수 거듭제곱np.var()분산
np.inf무한대np.log()자연 로그np.std()표준편차
np.abs()절대값np.sum()모든 원소 덧셈np.min()최솟값
np.floor()소수점 버림np.cumsum()모든 원소 누적 덧셈np.max()최댓값
np.ceil()소수점 올림np.prod()모든 원소 곱셈np.argmin()최솟값의 인덱스
np.round()반올림np.dot()내적 계산np.argmax()최댓값의 인덱스
np.diff()원소 간 차이np.size()원소 개수np.argsort()오름차순 인덱스
ar1 = np.array([1, 4, 3, 5, 2, 4, 3, 5, 1])

np.min(ar1) # np.int64(1)
np.max(ar1) # np.int64(5)

# 값이 여러개 있을 대 첫 번째 인덱스만 반환
np.argmin(ar1) # np.int64(0)
np.argmax(ar1) # np.int64(3)

# 배열 원소를 오름차순 정렬하고 인덱스만 반환
np.argsort(ar1)
# array([0, 8, 4, 6, 2, 5, 1, 3, 7])

무작위 값 추출

  • 시드 설정
seed = 1

np.random.seed(seed)
np.random.rand()
for i in range(5):
    np.random.seed(seed)
    print(np.random.randint(0, 5, 1))
for i in range(10):
    lotto = np.random.choice(range(1,46), 6, replace=False)
    lotto = [i.item() for i in lotto]
    print(sorted(lotto))

Pandas 기초

Pandas

  • 시리즈(Series) : 원소를 나열한 1차원 배열
  • 데이터프레임(DataFrame) : 원소인 시리즈를 나열한 2차원 배열
    • 행(row)과 열(column)을 갖는 2차원 자료형
    • 행 또는 열 하나만 선택하면 시리즈로 반환

데이터 프레임의 명칭

  • 행(Row) : Index
    • 관측값(Observation), 레코드(Record)
  • 열(Column) : Columns
    • 변수(Variable), 특성(Feature)

시리즈

생성 및 확인

  • 원소에 문자열이 포함되면 object가 되어 원소의 자료형을 유지
li1 = [1, 2, 3]

ar1 = np.array(li1)
ar1 
# array([1, 2, 3])

sr = pd.Series(li1)
sr
# 0    1
# 1    2
# 2    3
# dtype: int64
li1 = [1, 2.0, 3]

ar1 = np.array(li1)
ar1 
# array([1., 2., 3.])

sr = pd.Series(li1)
sr
# 0    1.0
# 1    2.0
# 2    3.0
# dtype: float64
li1 = [1, 2.0, '3']

ar1 = np.array(li1)
ar1 
# array(['1', '2.0', '3'], dtype='<U32')

sr = pd.Series(li1)
sr
# 0      1
# 1    2.0
# 2      3
# dtype: object
type(sr) # pandas.core.series.Series
sr.ndim # 1
sr.shape # (3,)
sr.size # 3
sr.dtype # dtype('O')
  • 시리즈 원소별 자료형 확인
for i in sr:
    print(type(i))
# <class 'int'>
# <class 'float'>
# <class 'str'>

자료형 변환

sr.astype(str) + '1'
# 0      11
# 1    2.01
# 2      31
# dtype: object
sr.astype(int) + 1
# 0    2
# 1    3
# 2    4
# dtype: int64
sr.astype(float) + 1
# 0    2.0
# 1    3.0
# 2    4.0
# dtype: float64
sr.astype(bool)
# 0    True
# 1    True
# 2    True
# dtype: bool

인덱스 설정 및 변경

  • index : 인덱스 객체 확인
sr.index # RangeIndex(start=0, stop=3, step=1)
  • 인덱스 설정
pd.Series(li1, index=[1, 2, 3])
# 1      1
# 2    2.0
# 3      3
# dtype: object
pd.Series(li1, index=[1.0, 2.0, 3.0])
# 1.0      1
# 2.0    2.0
# 3.0      3
# dtype: object
pd.Series(li1, index=['a', 'b', 'c'])
# a      1
# b    2.0
# c      3
# dtype: object
pd.Series(li1, index=[1, 1, 1])
# 1      1
# 1    2.0
# 1      3
# dtype: object
  • 인덱스 변경
sr.index = [1, 2, 3]
sr
# 1      1
# 2    2.0
# 3      3
# dtype: object
sr.index = [1.0, 2.0, 3.0]
sr
# 1.0      1
# 2.0    2.0
# 3.0      3
# dtype: object
sr.index = ['a', 'b', 'c']
sr
# a      1
# b    2.0
# c      3
# dtype: object
sr.index = [1, 1, 1]
sr
# 1      1
# 1    2.0
# 1      3
# dtype: object

딕셔너리로 시리즈 생성

  • 딕셔너리의 키를 시리즈의 인덱스로 지정
  • 키와 다른 인덱스를 추가하면 값을 결측값으로 채움
di = {'a': 1, 'b': 2, 'c': 3}

sr = pd.Series(di)
sr
# a    1
# b    2
# c    3
# dtype: int64

인덱싱 및 슬라이싱

  • 인덱스의 크기 비교X
sr
# a    1
# b    2
# c    3
# dtype: int64
  • 인덱싱
sr[0]
# FutureWarning
# np.int64(1)

sr.iloc[0]
# np.int64(1)

sr['a']
# np.int64(1)
  • 슬라이싱
sr[0:3]
# a    1
# b    2
# c    3
# dtype: int64

sr['a':'c']
# a    1
# b    2
# c    3
# dtype: int64

고급 인덱싱(팬시 인덱싱, 불리언 인덱싱)

  • 팬시 인덱싱
sr[[0, 2]]
# a    1
# c    3
# dtype: int64
  • 불리언 인덱싱
sr[[True, False, False]]
# a    1
# dtype: int64

sr[sr < 3]
# a    1
# b    2
# dtype: int64

iloc 인덱서

  • 정수 인덱스를 원소로 선택
  • 불리언 인덱싱 지원 X
sr.iloc[0] 
# np.int64(1)

sr.iloc[0:3]
# a    1
# b    2
# c    3
# dtype: int64

sr.iloc[[0]]
# a    1
# dtype: int64

sr.iloc[[0, 2]]
# a    1
# c    3
# dtype: int64

# 불리언 인덱싱 지원 X
sr.iloc[sr < 3]
# ValueError: iLocation based boolean indexing cannot use an indexable as a mask

loc 인덱서

  • 행이름으로 원소를 선택
  • 시리즈에 대해 인덱싱을 할 때, loc 인덱서가 생략되었다고 보는 것이 좋음
sr.loc['a']
# np.int64(1)

sr.loc['a':'c']
# a    1
# b    2
# c    3
# dtype: int64

sr.loc[['a']]
# a    1
# dtype: int64

sr.loc[['a', 'c']]
# a    1
# c    3
# dtype: int64

sr.loc[sr < 3]
# a    1
# b    2
# dtype: int64

원소 추가, 변경 및 삭제

sr
# a    1
# b    2
# c    3
# dtype: int64
  • 추가
sr.loc['d'] = 4
sr
# a    1
# b    2
# c    3
# d    4
# dtype: int64
  • 변경
sr.loc['d'] = 5
sr
# a    1
# b    2
# c    3
# d    5
# dtype: int64
  • 삭제
    • index 매개변수에 삭제할 행이름을 스칼라 또는 리스트로 지정
    • 실행 결과를 원본에 재할당해야 반영
sr = sr.drop(index='d')
sr
# a    1
# b    2
# c    3
# dtype: int64

비교 연산

  • 시리즈로 비교 연산을 실행하면, 원소가 True 또는 False인 불리언 시리즈를 반환
  • 논리 연산자는 진리값 스칼라간에서 정상적으로 사용
    • 불리언 시리즈에는 적용X
sr >= 1
# a    True
# b    True
# c    True
# dtype: bool
for i in sr:
    print(i >= 1 and i < 3)
# True
# True
# False

sr >= 1 and sr < 3
# ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

비트 연산자

(sr >= 1) & (sr < 3)
# a     True
# b     True
# c    False
# dtype: bool
(sr >= 1) | (sr < 3)
# a    True
# b    True
# c    True
# dtype: bool
(sr >= 1) ^ (sr < 3)
# a    False
# b    False
# c     True
# dtype: bool
  • 전체 코드를 괄호로 감싸지 않으면 결과가 달라짐
~((sr >= 1) & (sr < 3))
# a    False
# b    False
# c     True
# dtype: bool

데이터프레임

생성 및 확인

li2 = [[1, 2, 3], [4, 5.0, '6']]

# 넘파이 배열
np.array(li2)
# array([['1', '2', '3'],
#        ['4', '5.0', '6']], dtype='<U32')

# 데이터프레임
df = pd.DataFrame(li2)
df
#   0	1	2
# 0	1	2.0	3
# 1	4	5.0	6
df.ndim # 2
df.shape # (2, 3)
df.index # RangeIndex(start=0, stop=2, step=1)
df.columns # RangeIndex(start=0, stop=3, step=1)

df.dtypes
# 0      int64
# 1    float64
# 2     object
# dtype: object

df.values
# array([[1, 2.0, 3],
#        [4, 5.0, '6']], dtype=object)

df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 2 entries, 0 to 1
# Data columns (total 3 columns):
#  #   Column  Non-Null Count  Dtype  
# ---  ------  --------------  -----  
#  0   0       2 non-null      int64  
#  1   1       2 non-null      float64
#  2   2       2 non-null      object 
# dtypes: float64(1), int64(1), object(1)
# memory usage: 180.0+ bytes

행이름과 열이름 변경

  • index 로 행이름 변경
df.index = range(1, 3)
df
#   0	1	  2
# 1	1	2.0	3
# 2	4	5.0	6
  • columns 로 열이름 변경
df.columns = ['A', 'B', 'C']
df
#   A	B	  C
# 1	1	2.0	3
# 2	4	5.0	6
  • 생성할 때 행이름과 열이름 설정
pd.DataFrame(li2, index=range(1,3), columns=['A', 'B', 'C'])
#   A	B	  C
# 1	1	2.0	3
# 2	4	5.0	6

인덱서(iloc, loc)

df
#   A	B	  C
# 1	1	2.0	3
# 2	4	5.0	6
  • iloc 사용으로 행 제어
df.iloc[0, :]
# A      1
# B    2.0
# C      3
# Name: 1, dtype: object

df.iloc[0:2, :]
#   A	B	C
# 1	1	2.0	3
# 2	4	5.0	6

df.iloc[[1, 0], :]
#   A	B	C
# 2	4	5.0	6
# 1	1	2.0	3
  • iloc 사용으로 열 제어
df.iloc[:, 0]
# 1    1
# 2    4
# Name: A, dtype: int64

df.iloc[:, 0:2]
#   A	B
# 1	1	2.0
# 2	4	5.0

df.iloc[:, [1, 0]]
#   B	A
# 1	2.0	1
# 2	5.0	4
  • loc 사용으로 행 제어
df.loc[1, :]
# A      1
# B    2.0
# C      3
# Name: 1, dtype: object

df.loc[1:2, :]
#   A	B	C
# 1	1	2.0	3
# 2	4	5.0	6

df.loc[[2, 1], :]
#   A	B	C
# 2	4	5.0	6
# 1	1	2.0	3
  • loc 사용으로 열 제어
df.loc[:, 'A']
# 1    1
# 2    4
# Name: A, dtype: int64

df.loc[:, 'A':'B']
#   A	B
# 1	1	2.0
# 2	4	5.0

df.loc[:, ['B', 'A']]
#   B	A
# 1	2.0	1
# 2	5.0	4

행 / 열 추가, 변경 및 삭제

  • 행 추가
df.loc[4, :] = [7, 8, 9.0]
df
#   A	B	C
# 1	1.0	2.0	3
# 2	4.0	5.0	6
# 4	7.0	8.0	9.0
  • 열 추가
df.loc[:, 'D'] = ['a', 'b', 'c']
df
#   A	B	C	D
# 1	1.0	2.0	3	a
# 2	4.0	5.0	6	b
# 4	7.0	8.0	9.0	c
  • 셀 값 변경
df.loc[4, 'D'] = 'd'
df
#   A	B	C	D
# 1	1.0	2.0	3	a
# 2	4.0	5.0	6	b
# 4	7.0	8.0	9.0	d
  • 행 / 열 삭제
df = df.drop(index=4, columns='D')
df
#   A	B	C
# 1	1.0	2.0	3
# 2	4.0	5.0	6

마치며

지난 교육에서 2주 정도의 진도를 하루 만에 다 나간 것 같다. 한 번 배웠던 내용인데도 겨우 속도를 따라갔던 것 같다. NumPy Pandas는 이후 더 복잡한 내용이 많아지니까 시간 날 때마다 계속 문제를 풀면서 빨리 적응을 해야겠다.

profile
Hello I'm TaeHyunAn, Currently Studying Data Analysis

0개의 댓글