컬렉션(collection)
리스트(List)
리스트란?
- 리스트는 파이썬에서 가장 많이 사용되는 자료형 중 하나로, 여러 개의 값을 하나의 변수에 저장할 수 있는 데이터 구조입니다.
- 리스트는 대괄호([])를 사용하여 정의하며, 각 요소는 쉼표로 구분합니다.
- 리스트의 요소는 다양한 자료형(정수, 문자열, 다른 리스트 등)을 가질 수 있으며, 하나의 리스트에 다양한 자료형을 혼합할 수 있습니다.
리스트 생성
# 빈 리스트 생성
empty_list = []
# 정수형 리스트 생성
numbers = [1, 2, 3, 4, 5]
# 문자열 리스트 생성
fruits = ["사과", "바나나", "체리"]
# 다양한 자료형을 포함하는 리스트 생성
mixed_list = [1, "안녕", True, [1, 2, 3]]
리스트 접근 및 슬라이싱
- 리스트의 요소는 인덱스를 사용하여 접근할 수 있습니다. 인덱스는 0부터 시작합니다.
- 음수 인덱스를 사용하여 리스트의 끝에서부터 요소에 접근할 수도 있습니다.
fruits = ["사과", "바나나", "체리"]
# 인덱스를 사용한 접근
print(fruits[0]) # 출력: 사과
print(fruits[1]) # 출력: 바나나
print(fruits[2]) # 출력: 체리
# 음수 인덱스를 사용한 접근
print(fruits[-1]) # 출력: 체리
print(fruits[-2]) # 출력: 바나나
print(fruits[-3]) # 출력: 사과
# 리스트 슬라이싱
print(fruits[0:2]) # 출력: ['사과', '바나나']
print(fruits[1:]) # 출력: ['바나나', '체리']
print(fruits[:2]) # 출력: ['사과', '바나나']
print(fruits[:]) # 출력: ['사과', '바나나', '체리']
리스트 수정 및 삭제
- 리스트의 요소는 인덱스를 사용하여 수정할 수 있습니다.
- append(), extend(), insert(), remove(), pop(), clear() 등의 메서드를 사용하여 리스트를 수정할 수 있습니다.
fruits = ["사과", "바나나", "체리"]
# 요소 수정
fruits[1] = "블루베리"
print(fruits) # 출력: ['사과', '블루베리', '체리']
# 요소 추가
fruits.append("오렌지")
print(fruits) # 출력: ['사과', '블루베리', '체리', '오렌지']
# 요소 삽입
fruits.insert(1, "키위")
print(fruits) # 출력: ['사과', '키위', '블루베리', '체리', '오렌지']
# 요소 삭제
fruits.remove("블루베리")
print(fruits) # 출력: ['사과', '키위', '체리', '오렌지']
# 마지막 요소 삭제
fruits.pop()
print(fruits) # 출력: ['사과', '키위', '체리']
# 특정 인덱스의 요소 삭제
fruits.pop(1)
print(fruits) # 출력: ['사과', '체리']
# 리스트 초기화
fruits.clear()
print(fruits) # 출력: []
리스트 메서드
요소 추가
- append(x): 리스트의 끝에 요소 x를 추가합니다.
- extend(iterable): 반복 가능한 객체의 모든 요소를 리스트의 끝에 추가합니다.
- insert(i, x): 인덱스 i에 요소 x를 삽입합니다.
numbers = [1, 2, 3]
numbers.append(4)
print(numbers) # 출력: [1, 2, 3, 4]
numbers.extend([5, 6])
print(numbers) # 출력: [1, 2, 3, 4, 5, 6]
numbers.insert(3, 2.5)
print(numbers) # 출력: [1, 2, 3, 2.5, 4, 5, 6]
요소 삭제
- remove(x): 리스트에서 첫 번째로 나오는 요소 x를 삭제합니다.
- pop([i]): 인덱스 i에 있는 요소를 삭제하고 반환합니다. 인덱스를 지정하지 않으면 마지막 요소를 삭제하고 반환합니다.
- clear(): 리스트의 모든 요소를 삭제합니다.
numbers = [1, 2, 3, 2, 4, 5]
numbers.remove(2)
print(numbers) # 출력: [1, 3, 2, 4, 5]
numbers.pop(2)
print(numbers) # 출력: [1, 3, 4, 5]
numbers.clear()
print(numbers) # 출력: []
요소 찾기 및 개수 세기
- index(x[, start[, end]]): 리스트에서 첫 번째로 나오는 요소 x의 인덱스를 반환합니다.
- count(x): 리스트에서 요소 x의 개수를 셉니다.
numbers = [1, 2, 3, 2, 4, 2, 5]
print(numbers.index(2)) # 출력: 1
print(numbers.index(2, 2)) # 출력: 3
print(numbers.count(2)) # 출력: 3
리스트 정렬
- sort(key=None, reverse=False): 리스트를 정렬합니다. key는 정렬 기준이 되는 함수, reverse는 정렬 순서를 지정합니다.
- reverse(): 리스트의 요소 순서를 반대로 뒤집습니다.
numbers = [5, 2, 9, 1, 5, 6]
numbers.sort()
print(numbers) # 출력: [1, 2, 5, 5, 6, 9]
numbers.sort(reverse=True)
print(numbers) # 출력: [9, 6, 5, 5, 2, 1]
numbers.reverse()
print(numbers) # 출력: [1, 2, 5, 5, 6, 9]
리스트 복사
- copy(): 리스트의 얕은 복사본을 만듭니다.
numbers = [1, 2, 3, 4, 5]
numbers_copy = numbers.copy()
print(numbers_copy) # 출력: [1, 2, 3, 4, 5]
리스트 컴프리헨션 (List Comprehensions)
리스트 컴프리헨션이란?
- 리스트 컴프리헨션은 기존 리스트를 기반으로 새로운 리스트를 간단하고 직관적으로 생성하는 방법입니다.
- 반복문과 조건문을 한 줄로 결합하여 복잡한 리스트를 생성할 수 있으며, 코드의 가독성과 효율성을 높입니다.
- 리스트 컴프리헨션은 기존의 for 루프를 간결하게 표현할 수 있어 더 읽기 쉽고 유지 관리하기 쉬운 코드를 작성할 수 있습니다.
기본 형태
리스트 컴프리헨션의 기본 형태는 다음과 같습니다:
[expression for item in iterable if condition]
- expression: 각 요소에 대해 실행할 표현식입니다.
- item: 반복 가능한 객체(예: 리스트, 튜플, 문자열 등)에서 가져온 요소입니다.
- iterable: 반복 가능한 객체입니다.
- condition: 선택 사항으로, 이 조건이 참인 경우에만 요소가 리스트에 포함됩니다.
예제
예제 1: 짝수만 포함된 리스트 생성
1부터 10까지의 숫자 중에서 짝수만 포함된 리스트를 생성합니다.
even_numbers = [x for x in range(1, 11) if x % 2 == 0]
print(even_numbers) # 출력: [2, 4, 6, 8, 10]
- 여기서 x는 1부터 10까지의 숫자이며, x % 2 == 0 조건은 x가 짝수인 경우에만 참이 됩니다.
- 결과적으로, [2, 4, 6, 8, 10] 형태의 리스트가 생성됩니다.
예제 2: 숫자의 제곱을 포함한 리스트 생성
1부터 10까지의 숫자의 제곱을 포함한 리스트를 생성합니다.
squares = [x**2 for x in range(1, 11)]
print(squares) # 출력: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
- 여기서 x**2는 x의 제곱을 계산합니다.
- 결과적으로, [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 형태의 리스트가 생성됩니다.
예제 3: 두 리스트의 Cartesian product 생성
두 리스트의 Cartesian product(데카르트 곱)를 생성합니다.
colors = ["red", "green", "blue"]
objects = ["ball", "cube"]
cartesian_product = [(color, obj) for color in colors for obj in objects]
print(cartesian_product)
# 출력: [('red', 'ball'), ('red', 'cube'), ('green', 'ball'), ('green', 'cube'), ('blue', 'ball'), ('blue', 'cube')]
- 여기서 for color in colors와 for obj in objects는 중첩된 반복문을 나타냅니다.
- 각 색상과 객체의 조합을 튜플로 생성하여 리스트에 추가합니다.
- 결과적으로, [('red', 'ball'), ('red', 'cube'), ('green', 'ball'), ('green', 'cube'), ('blue', 'ball'), ('blue', 'cube')] 형태의 리스트가 생성됩니다.
추가 예제
예제 4: 문자열의 각 문자를 대문자로 변환
주어진 문자열의 각 문자를 대문자로 변환하여 리스트를 생성합니다.
text = "hello"
uppercase_letters = [char.upper() for char in text]
print(uppercase_letters) # 출력: ['H', 'E', 'L', 'L', 'O']
- 여기서 char.upper()는 각 문자를 대문자로 변환합니다.
- 결과적으로, ['H', 'E', 'L', 'L', 'O'] 형태의 리스트가 생성됩니다.
예제 5: 리스트의 요소 중 조건을 만족하는 요소만 선택
1부터 20까지의 숫자 중에서 3의 배수만 포함된 리스트를 생성합니다.
multiples_of_three = [x for x in range(1, 21) if x % 3 == 0]
print(multiples_of_three) # 출력: [3, 6, 9, 12, 15, 18]
- 여기서 x % 3 == 0 조건은 x가 3의 배수인 경우에만 참이 됩니다.
- 결과적으로, [3, 6, 9, 12, 15, 18] 형태의 리스트가 생성됩니다.
예제 6: 리스트의 요소를 조건에 따라 변환
1부터 10까지의 숫자 중에서 짝수는 제곱하고, 홀수는 그대로 포함된 리스트를 생성합니다.
numbers = [x**2 if x % 2 == 0 else x for x in range(1, 11)]
print(numbers) # 출력: [1, 4, 3, 16, 5, 36, 7, 64, 9, 100]
- 여기서 x**2 if x % 2 == 0 else x 표현식은 x가 짝수인 경우 제곱을 계산하고, 홀수인 경우 그대로 x를 반환합니다.
- 결과적으로, [1, 4, 3, 16, 5, 36, 7, 64, 9, 100] 형태의 리스트가 생성됩니다.
예제 7: 중첩 리스트 컴프리헨션
2차원 리스트의 요소를 평탄화(flatten)하여 1차원 리스트로 변환합니다.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # 출력: [1, 2, 3, 4, 5, 6, 7, 8, 9]
- 여기서 for row in matrix는 2차원 리스트의 각 행을 반복하고, for num in row는 각 행의 요소를 반복합니다.
- 각 요소를 하나의 리스트로 평탄화하여 [1, 2, 3, 4, 5, 6, 7, 8, 9] 형태의 리스트가 생성됩니다.
리스트 컴프리헨션의 장점
- 간결성: 리스트 컴프리헨션을 사용하면 더 간결하고 읽기 쉬운 코드를 작성할 수 있습니다.
- 가독성: 한 줄로 작성된 컴프리헨션은 반복문을 사용한 코드보다 가독성이 높습니다.
- 성능: 리스트 컴프리헨션은 일반적인 for 루프보다 더 빠르게 실행될 수 있습니다. 이는 컴프리헨션이 내부적으로 최적화되어 있기 때문입니다.
리스트 컴프리헨션의 주의사항
- 과도한 사용 지양: 너무 복잡한 리스트 컴프리헨션은 오히려 가독성을 떨어뜨릴 수 있습니다. 간단한 경우에만 사용하는 것이 좋습니다.
- 디버깅 어려움: 한 줄로 작성된 리스트 컴프리헨션은 디버깅이 어려울 수 있습니다. 복잡한 로직은 여러 줄로 나누어 작성하는 것이 좋습니다.
5. 예제 및 실습 문제
문제 1: 리스트에서 중복된 요소를 제거하는 함수 작성
def remove_duplicates(lst):
return list(set(lst))
numbers = [1, 2, 3, 2, 4, 5, 3, 6]
unique_numbers = remove_duplicates(numbers)
print(unique_numbers) # 출력: 중복이 제거된 리스트
문제 2: 리스트에서 가장 큰 값과 가장 작은 값을 찾는 함수 작성
def find_max_min(lst):
return max(lst), min(lst)
numbers = [1, 2, 3, 4, 5]
max_value, min_value = find_max_min(numbers)
print(f"최대값: {max_value}, 최소값: {min_value}") # 출력: 최대값과 최소값
문제 3: 리스트의 모든 요소를 제곱한 값을 갖는 새 리스트를 생성하는 함수 작성
def square_elements(lst):
return [x**2 for x in lst]
numbers = [1, 2, 3, 4, 5]
squared_numbers = square_elements(numbers)
print(squared_numbers) # 출력: [1, 4, 9, 16, 25]
딕셔너리(Dictionary)
딕셔너리란?
- 딕셔너리는 키-값 쌍으로 데이터를 저장하는 자료형입니다.
- 딕셔너리는 중괄호 {}를 사용하여 정의하며, 각 키와 값은 콜론 :으로 구분되고, 쌍은 쉼표 ,로 구분됩니다.
- 딕셔너리의 키는 불변(immutable) 자료형이어야 하며, 값은 어떤 자료형도 가능합니다.
- 딕셔너리는 해시 테이블을 사용하여 구현되므로, 키를 통해 값을 빠르게 검색할 수 있습니다.
딕셔너리 생성
# 빈 딕셔너리 생성
empty_dict = {}
# 키-값 쌍을 포함한 딕셔너리 생성
person = {
"name": "홍길동",
"age": 27,
"city": "서울"
}
# dict() 함수를 사용하여 딕셔너리 생성
person = dict(name="홍길동", age=27, city="서울")
딕셔너리 접근 및 수정
- 딕셔너리의 요소는 키를 사용하여 접근하고 수정할 수 있습니다.
person = {"name": "홍길동", "age": 27, "city": "서울"}
# 키를 사용한 값 접근
print(person["name"]) # 출력: 홍길동
print(person["age"]) # 출력: 27
# 값 수정
person["age"] = 28
print(person) # 출력: {'name': '홍길동', 'age': 28, 'city': '서울'}
# 새 키-값 쌍 추가
person["job"] = "개발자"
print(person) # 출력: {'name': '홍길동', 'age': 28, 'city': '서울', 'job': '개발자'}
딕셔너리 메서드
요소 추가 및 업데이트
- update() 메서드를 사용하여 다른 딕셔너리의 키-값 쌍을 추가하거나 업데이트할 수 있습니다.
person = {"name": "홍길동", "age": 27}
person.update({"city": "서울", "job": "개발자"})
print(person) # 출력: {'name': '홍길동', 'age': 27, 'city': '서울', 'job': '개발자'}
요소 삭제
- del 키워드를 사용하거나 pop() 메서드를 사용하여 요소를 삭제할 수 있습니다.
- popitem() 메서드는 마지막 키-값 쌍을 삭제하고 반환합니다.
- clear() 메서드는 딕셔너리의 모든 요소를 삭제합니다.
person = {"name": "홍길동", "age": 27, "city": "서울"}
# 특정 요소 삭제
del person["age"]
print(person) # 출력: {'name': '홍길동', 'city': '서울'}
# pop() 메서드를 사용한 삭제
city = person.pop("city")
print(city) # 출력: 서울
print(person) # 출력: {'name': '홍길동'}
# popitem() 메서드를 사용한 삭제
person["age"] = 27
last_item = person.popitem()
print(last_item) # 출력: ('age', 27)
print(person) # 출력: {'name': '홍길동'}
# clear() 메서드를 사용한 모든 요소 삭제
person.clear()
print(person) # 출력: {}
딕셔너리 메서드 (계속)
요소 검색
- keys(), values(), items() 메서드를 사용하여 딕셔너리의 키, 값, 키-값 쌍을 반환할 수 있습니다.
person = {"name": "홍길동", "age": 27, "city": "서울"}
# 키 리스트 반환
keys = person.keys()
print(keys) # 출력: dict_keys(['name', 'age', 'city'])
# 값 리스트 반환
values = person.values()
print(values) # 출력: dict_values(['홍길동', 27, '서울'])
# 키-값 쌍 리스트 반환
items = person.items()
print(items) # 출력: dict_items([('name', '홍길동'), ('age', 27), ('city', '서울')])
요소 존재 여부 확인
- in 연산자를 사용하여 특정 키가 딕셔너리에 존재하는지 확인할 수 있습니다.
person = {"name": "홍길동", "age": 27, "city": "서울"}
# 키 존재 여부 확인
print("name" in person) # 출력: True
print("job" in person) # 출력: False
딕셔너리 컴프리헨션 (Dictionary Comprehensions)
딕셔너리 컴프리헨션이란?
- 딕셔너리 컴프리헨션은 기존의 리스트 컴프리헨션과 유사한 방식으로 딕셔너리를 간결하고 직관적으로 생성하는 방법입니다.
- 딕셔너리 컴프리헨션은 반복문과 조건문을 결합하여 새로운 딕셔너리를 생성할 수 있습니다.
- 이 방법을 사용하면 한 줄의 코드로 복잡한 딕셔너리를 생성할 수 있어 코드의 가독성과 효율성을 높입니다.
기본 형태
딕셔너리 컴프리헨션의 기본 형태는 다음과 같습니다:
{키_표현식: 값_표현식 for 아이템 in 반복가능객체 if 조건}
- 키_표현식: 딕셔너리의 키를 생성하는 표현식입니다.
- 값_표현식: 딕셔너리의 값을 생성하는 표현식입니다.
- 아이템: 반복 가능한 객체(예: 리스트, 튜플, 문자열 등)에서 가져온 요소입니다.
- 반복가능객체: 반복 가능한 객체입니다.
- 조건: 선택 사항으로, 이 조건이 참인 경우에만 아이템이 딕셔너리에 포함됩니다.
예제
예제 1: 숫자의 제곱을 값으로 갖는 딕셔너리 생성
1부터 5까지의 숫자를 키로 하고, 그 제곱을 값으로 갖는 딕셔너리를 생성합니다.
squares = {x: x**2 for x in range(1, 6)}
print(squares) # 출력: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
- 여기서 x는 1부터 5까지의 숫자이며, x**2는 해당 숫자의 제곱입니다.
- 결과적으로, {1: 1, 2: 4, 3: 9, 4: 16, 5: 25} 형태의 딕셔너리가 생성됩니다.
예제 2: 두 리스트를 사용하여 딕셔너리 생성
keys 리스트와 values 리스트를 사용하여 딕셔너리를 생성합니다.
keys = ["name", "age", "city"]
values = ["홍길동", 27, "서울"]
person = {keys[i]: values[i] for i in range(len(keys))}
print(person) # 출력: {'name': '홍길동', 'age': 27, 'city': '서울'}
- keys 리스트와 values 리스트의 길이는 동일해야 합니다.
- for i in range(len(keys))는 0부터 len(keys)-1까지의 인덱스를 반복합니다.
- keys[i]는 딕셔너리의 키가 되고, values[i]는 해당 키에 대한 값이 됩니다.
- 결과적으로, {'name': '홍길동', 'age': 27, 'city': '서울'} 형태의 딕셔너리가 생성됩니다.
추가 예제
예제 3: 조건을 사용한 딕셔너리 생성
1부터 10까지의 숫자 중 짝수만 키로 하고, 그 제곱을 값으로 갖는 딕셔너리를 생성합니다.
even_squares = {x: x**2 for x in range(1, 11) if x % 2 == 0}
print(even_squares) # 출력: {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
- 여기서 x % 2 == 0 조건은 x가 짝수인 경우에만 참이 됩니다.
- 결과적으로, {2: 4, 4: 16, 6: 36, 8: 64, 10: 100} 형태의 딕셔너리가 생성됩니다.
예제 4: 문자열의 각 문자의 빈도수 계산
문자열에서 각 문자의 빈도수를 계산하여 딕셔너리로 생성합니다.
text = "hello world"
frequency = {char: text.count(char) for char in set(text)}
print(frequency) # 출력: {'d': 1, 'h': 1, 'e': 1, 'o': 2, 'l': 3, 'r': 1, ' ': 1, 'w': 1}
- set(text)는 문자열 text에서 중복된 문자를 제거하여 유일한 문자만을 포함하는 집합을 만듭니다.
- text.count(char)는 문자열 text에서 문자 char의 빈도수를 계산합니다.
- 결과적으로, 각 문자의 빈도수를 나타내는 딕셔너리가 생성됩니다.
예제 5: 키와 값을 뒤집어서 새로운 딕셔너리 생성
기존 딕셔너리에서 키와 값을 뒤집어서 새로운 딕셔너리를 생성합니다.
original_dict = {'a': 1, 'b': 2, 'c': 3}
inverted_dict = {value: key for key, value in original_dict.items()}
print(inverted_dict) # 출력: {1: 'a', 2: 'b', 3: 'c'}
- original_dict.items()는 딕셔너리의 키-값 쌍을 반환합니다.
- for key, value in original_dict.items()는 각 키-값 쌍을 반복합니다.
- value: key는 기존의 값이 새로운 키가 되고, 기존의 키가 새로운 값이 됩니다.
- 결과적으로, 키와 값이 뒤집힌 딕셔너리가 생성됩니다.
5. 예제 및 실습 문제
문제 1: 학생들의 성적을 저장하고, 평균 점수를 계산하는 프로그램 작성
python코드 복사
students = {
"홍길동": 85,
"김철수": 90,
"이영희": 78,
"박영수": 92
}
# 평균 점수 계산
average_score = sum(students.values()) / len(students)
print(f"평균 점수: {average_score}") # 출력: 평균 점수: 86.25
문제 2: 딕셔너리를 사용하여 단어의 빈도를 계산하는 프로그램 작성
text = "apple banana apple orange banana apple"
words = text.split()
# 단어 빈도 계산
word_count = {}
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print(word_count) # 출력: {'apple': 3, 'banana': 2, 'orange': 1}
문제 3: 두 딕셔너리를 병합하는 함수 작성
python코드 복사
def merge_dicts(dict1, dict2):
merged_dict = dict1.copy()
merged_dict.update(dict2)
return merged_dict
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged_dict = merge_dicts(dict1, dict2)
print(merged_dict) # 출력: {'a': 1, 'b': 3, 'c': 4}
튜플(Tuple)
튜플이란?
- 튜플은 파이썬의 기본 자료형 중 하나로, 여러 개의 값을 하나의 변수에 저장할 수 있는 데이터 구조입니다.
- 리스트와 비슷하지만, 튜플은 불변(immutable)하다는 점에서 차이가 있습니다. 즉, 한 번 생성된 튜플의 요소는 변경할 수 없습니다.
- 튜플은 소괄호 ()를 사용하여 정의하며, 각 요소는 쉼표 ,로 구분됩니다.
리스트와 튜플의 차이
파이썬에서 리스트(List)와 튜플(Tuple)은 모두 시퀀스 자료형으로, 여러 요소를 하나의 변수에 저장할 수 있습니다. 그러나 두 자료형 사이에는 몇 가지 중요한 차이점이 있습니다. 이 섹션에서는 리스트와 튜플의 주요 차이점을 자세히 설명하고, 각각의 장단점을 다룹니다.
리스트와 튜플의 차이점
1. 변경 가능성 (Mutability)
- 리스트는 변경 가능(mutable)합니다. 즉, 리스트의 요소를 추가, 수정, 삭제할 수 있습니다.
- 튜플은 변경 불가능(immutable)합니다. 즉, 튜플이 생성된 후에는 요소를 변경할 수 없습니다.
python코드 복사
# 리스트는 변경 가능
fruits_list = ["사과", "바나나", "체리"]
fruits_list[1] = "블루베리" # 요소 변경
print(fruits_list) # 출력: ['사과', '블루베리', '체리']
# 튜플은 변경 불가능
fruits_tuple = ("사과", "바나나", "체리")
# fruits_tuple[1] = "블루베리" # 오류 발생: TypeError: 'tuple' object does not support item assignment
2. 사용 용도
- 리스트는 요소의 추가, 삭제, 변경이 필요한 경우 사용됩니다.
- 튜플은 요소가 고정된 경우(변경되지 않아야 할 데이터)를 저장할 때 사용됩니다. 예를 들어, 함수의 반환값을 여러 개 묶어서 반환하거나, 고정된 설정 값을 저장할 때 튜플이 유용합니다.
3. 성능
- 튜플은 리스트보다 메모리 사용량이 적고, 생성 시간이 더 빠릅니다. 이는 튜플이 불변성이 있기 때문에 가능한 최적화 덕분입니다.
- 따라서, 변경이 필요 없는 데이터를 저장할 때는 튜플을 사용하는 것이 성능 면에서 유리합니다.
import sys
list_example = [1, 2, 3, 4, 5]
tuple_example = (1, 2, 3, 4, 5)
print(sys.getsizeof(list_example)) # 출력: 리스트의 메모리 사용량
print(sys.getsizeof(tuple_example)) # 출력: 튜플의 메모리 사용량
4. 메서드
- 리스트는 요소를 변경할 수 있기 때문에 많은 메서드를 제공합니다. 예를 들어, append(), extend(), insert(), remove(), pop(), clear(), sort(), reverse() 등의 메서드가 있습니다.
- 튜플은 불변이기 때문에 제공하는 메서드가 적습니다. 주요 메서드는 count()와 index()입니다.
# 리스트 메서드 예시
numbers_list = [1, 2, 3]
numbers_list.append(4)
print(numbers_list) # 출력: [1, 2, 3, 4]
numbers_list.remove(2)
print(numbers_list) # 출력: [1, 3, 4]
# 튜플 메서드 예시
numbers_tuple = (1, 2, 3, 2, 4)
print(numbers_tuple.count(2)) # 출력: 2
print(numbers_tuple.index(3)) # 출력: 2
5. 자료형의 불변성
- 튜플은 불변이므로, 딕셔너리의 키로 사용할 수 있습니다. 리스트는 변경 가능하기 때문에 딕셔너리의 키로 사용할 수 없습니다.
# 튜플을 딕셔너리의 키로 사용
my_dict = {(1, 2): "a", (3, 4): "b"}
print(my_dict[(1, 2)]) # 출력: a
# 리스트는 딕셔너리의 키로 사용할 수 없음
# my_dict = {[1, 2]: "a", [3, 4]: "b"} # 오류 발생: TypeError: unhashable type: 'list'
리스트와 튜플의 장단점
리스트의 장점
- 유연성: 요소를 추가, 삭제, 수정할 수 있어 데이터 조작이 용이합니다.
- 메서드 제공: 다양한 메서드를 제공하여 데이터 조작이 편리합니다.
리스트의 단점
- 메모리 사용: 불변 데이터 구조인 튜플보다 메모리를 더 많이 사용합니다.
- 성능: 생성 속도가 튜플보다 느립니다.
튜플의 장점
- 불변성: 변경할 수 없는 데이터를 안전하게 저장할 수 있습니다.
- 메모리 효율성: 리스트보다 메모리를 적게 사용합니다.
- 성능: 생성 속도가 리스트보다 빠릅니다.
- 해시 가능: 딕셔너리의 키로 사용할 수 있습니다.
튜플의 단점
- 유연성 부족: 한 번 생성된 튜플의 요소를 변경할 수 없습니다.
- 메서드 부족: 리스트에 비해 제공하는 메서드가 적습니다.
리스트와 튜플을 선택하는 기준
- 변경 가능 여부: 요소를 변경해야 하는 경우 리스트를 사용하고, 변경할 필요가 없는 경우 튜플을 사용합니다.
- 성능 요구 사항: 메모리 사용량을 최소화하고 빠른 생성 속도가 필요한 경우 튜플을 사용합니다.
- 사용 용도: 함수의 반환값을 여러 개 묶어서 반환하거나, 설정 값을 고정하여 저장하는 경우 튜플을 사용합니다.
튜플 생성
기본 생성 방법
# 빈 튜플 생성
empty_tuple = ()
# 여러 요소를 포함하는 튜플 생성
fruit_tuple = ("사과", "바나나", "체리")
# 튜플은 다양한 자료형을 포함할 수 있습니다.
mixed_tuple = (1, "안녕", 3.14, True)
요소가 하나인 튜플 생성
- 요소가 하나인 튜플을 생성할 때는 요소 뒤에 쉼표 ,를 추가해야 합니다. 그렇지 않으면 일반적인 자료형으로 인식됩니다.
single_element_tuple = (1,)
not_a_tuple = (1)
print(type(single_element_tuple)) # 출력: <class 'tuple'>
print(type(not_a_tuple)) # 출력: <class 'int'>
튜플 생성 시 괄호 생략
# 괄호를 생략하여 튜플 생성
fruit_tuple = "사과", "바나나", "체리"
print(fruit_tuple) # 출력: ('사과', '바나나', '체리')
print(type(fruit_tuple)) # 출력: <class 'tuple'>
튜플 접근 및 슬라이싱
- 튜플의 요소는 인덱스를 사용하여 접근할 수 있습니다. 인덱스는 0부터 시작합니다.
- 슬라이싱을 사용하여 튜플의 일부를 추출할 수 있습니다.
fruit_tuple = ("사과", "바나나", "체리")
# 인덱스를 사용한 접근
print(fruit_tuple[0]) # 출력: 사과
print(fruit_tuple[1]) # 출력: 바나나
print(fruit_tuple[2]) # 출력: 체리
# 음수 인덱스를 사용한 접근
print(fruit_tuple[-1]) # 출력: 체리
print(fruit_tuple[-2]) # 출력: 바나나
print(fruit_tuple[-3]) # 출력: 사과
# 슬라이싱
print(fruit_tuple[0:2]) # 출력: ('사과', '바나나')
print(fruit_tuple[1:]) # 출력: ('바나나', '체리')
print(fruit_tuple[:2]) # 출력: ('사과', '바나나')
print(fruit_tuple[:]) # 출력: ('사과', '바나나', '체리')
튜플 연산
- 튜플은 + 연산자를 사용하여 결합(concatenate)할 수 있으며, `` 연산자를 사용하여 반복(repeat)할 수 있습니다.
python코드 복사
fruit_tuple = ("사과", "바나나")
veg_tuple = ("당근", "브로콜리")
# 튜플 결합
combined_tuple = fruit_tuple + veg_tuple
print(combined_tuple) # 출력: ('사과', '바나나', '당근', '브로콜리')
# 튜플 반복
repeated_tuple = fruit_tuple * 2
print(repeated_tuple) # 출력: ('사과', '바나나', '사과', '바나나')
튜플의 불변성 (Immutability)
- 튜플은 한 번 생성되면 그 요소를 변경할 수 없습니다. 하지만, 튜플 내의 가변 객체(예: 리스트)는 변경할 수 있습니다.
python코드 복사
fruit_tuple = ("사과", "바나나", "체리")
# 요소 변경 시도 (오류 발생)
# fruit_tuple[0] = "오렌지" # TypeError: 'tuple' object does not support item assignment
# 가변 객체를 포함한 튜플
nested_list = ([1, 2, 3], [4, 5, 6])
nested_list[0][1] = 9
print(nested_list) # 출력: ([1, 9, 3], [4, 5, 6])
튜플의 메서드
- 튜플은 리스트와 달리 몇 가지 메서드만 제공합니다. 대표적으로 count()와 index() 메서드가 있습니다.
count()
- 튜플에서 특정 요소의 개수를 셉니다.
python코드 복사
fruit_tuple = ("사과", "바나나", "체리", "사과")
print(fruit_tuple.count("사과")) # 출력: 2
index()
- 튜플에서 특정 요소의 첫 번째 인덱스를 반환합니다.
python코드 복사
fruit_tuple = ("사과", "바나나", "체리", "사과")
print(fruit_tuple.index("바나나")) # 출력: 1
튜플 언패킹 (Tuple Unpacking)
- 튜플 언패킹을 사용하면 튜플의 각 요소를 별도의 변수에 할당할 수 있습니다.
fruit_tuple = ("사과", "바나나", "체리")
# 튜플 언패킹
apple, banana, cherry = fruit_tuple
print(apple) # 출력: 사과
print(banana) # 출력: 바나나
print(cherry) # 출력: 체리
# 일부 요소 무시하기 (언더스코어 사용)
_, banana, _ = fruit_tuple
print(banana) # 출력: 바나나
중첩된 튜플 (Nested Tuples)
- 중첩된 튜플은 튜플 내에 또 다른 튜플을 포함하는 튜플입니다.
python코드 복사
nested_tuple = (("a", "b", "c"), (1, 2, 3), (True, False))
# 중첩된 튜플 접근
print(nested_tuple[0]) # 출력: ('a', 'b', 'c')
print(nested_tuple[1][2]) # 출력: 3
튜플과 리스트 변환
- 튜플을 리스트로, 리스트를 튜플로 변환할 수 있습니다.
python코드 복사
# 튜플을 리스트로 변환
fruit_tuple = ("사과", "바나나", "체리")
fruit_list = list(fruit_tuple)
print(fruit_list) # 출력: ['사과', '바나나', '체리']
# 리스트를 튜플로 변환
fruit_list = ["사과", "바나나", "체리"]
fruit_tuple = tuple(fruit_list)
print(fruit_tuple) # 출력: ('사과', '바나나', '체리')
예제 및 실습 문제
문제 1: 두 개의 튜플을 합치는 함수 작성
python코드 복사
def merge_tuples(tuple1, tuple2):
return tuple1 + tuple2
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
merged_tuple = merge_tuples(tuple1, tuple2)
print(merged_tuple) # 출력: (1, 2, 3, 4, 5, 6)
문제 2: 튜플에서 최대값과 최소값을 찾는 함수 작성
python코드 복사
def find_max_min(t):
return max(t), min(t)
numbers = (5, 2, 9, 1, 5, 6)
max_value, min_value = find_max_min(numbers)
print(f"최대값: {max_value}, 최소값: {min_value}") # 출력: 최대값: 9, 최소값: 1
문제 3: 주어진 리스트를 튜플로 변환하고, 해당 튜플의 요소를 출력하는 함수 작성
def list_to_tuple(lst):
return tuple(lst)
lst = [10, 20, 30, 40, 50]
t = list_to_tuple(lst)
print(t) # 출력: (10, 20, 30, 40, 50)
이상으로 파이썬의 튜플에 대해 풍부하게 설명드렸습니다. 추가 질문이나 예제가 필요하시면 언제든지 말씀해주세요!
예외처리
파이썬의 예외 처리 (Exception Handling)
예외란?
- 예외는 프로그램 실행 중에 발생하는 예상치 못한 상황이나 오류를 의미합니다. 예외가 발생하면 프로그램의 정상적인 흐름이 중단됩니다.
- 파이썬에서는 이러한 예외를 예외 처리를 통해 관리하고, 프로그램의 비정상적인 종료를 방지할 수 있습니다.
예외 처리의 필요성
- 안정성: 예외 처리를 통해 프로그램이 중단되지 않고, 예상치 못한 상황에서도 안정적으로 동작할 수 있습니다.
- 디버깅: 예외 메시지를 통해 오류의 원인을 파악하고, 디버깅을 쉽게 할 수 있습니다.
- 사용자 경험: 사용자가 예외 상황에서도 적절한 피드백을 받을 수 있도록 도와줍니다.
예외 처리 구조
파이썬에서 예외 처리는 try, except, else, finally 블록을 사용하여 구현할 수 있습니다.
기본 구조
try:
# 예외가 발생할 가능성이 있는 코드
pass
except 예외타입:
# 예외가 발생했을 때 실행할 코드
pass
else:
# 예외가 발생하지 않았을 때 실행할 코드
pass
finally:
# 예외 발생 여부와 상관없이 항상 실행할 코드
pass
예제
1. 기본 예외 처리
try:
result = 10 / 0
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
2. 여러 예외 처리
try:
number = int(input("숫자를 입력하세요: "))
result = 10 / number
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
except ValueError:
print("유효한 숫자를 입력하세요.")
3. 모든 예외 처리
try:
number = int(input("숫자를 입력하세요: "))
result = 10 / number
except Exception as e:
print(f"예외가 발생했습니다: {e}")
4. else와 finally 블록 사용
python코드 복사
try:
number = int(input("숫자를 입력하세요: "))
result = 10 / number
except ZeroDivisionError:
print("0으로 나눌 수 없습니다.")
except ValueError:
print("유효한 숫자를 입력하세요.")
else:
print(f"결과는 {result}입니다.")
finally:
print("프로그램이 종료되었습니다.")
예외 객체 다루기
- 예외 객체는 발생한 예외에 대한 자세한 정보를 제공합니다. 예외 객체를 사용하면 예외 메시지를 출력하거나 로그로 남길 수 있습니다.
try:
number = int(input("숫자를 입력하세요: "))
result = 10 / number
except Exception as e:
print(f"예외가 발생했습니다: {e}")
사용자 정의 예외
- 사용자 정의 예외를 통해 특정 상황에서 커스텀 예외를 발생시키고 처리할 수 있습니다.
예제: 사용자 정의 예외
class CustomError(Exception):
pass
def check_positive(number):
if number < 0:
raise CustomError("음수는 허용되지 않습니다.")
try:
number = int(input("숫자를 입력하세요: "))
check_positive(number)
print("입력한 숫자는 양수입니다.")
except CustomError as e:
print(e)
예외 처리의 장점
- 프로그램의 안정성 향상: 예외 발생 시 적절히 처리하여 프로그램이 중단되지 않도록 합니다.
- 디버깅 용이: 예외 메시지를 통해 오류의 원인을 파악할 수 있습니다.
- 사용자 경험 개선: 사용자에게 명확한 오류 메시지를 제공하여 사용자의 혼란을 줄일 수 있습니다.
예외 처리의 단점
- 오류 은닉: 잘못된 예외 처리는 실제 문제를 은닉하여 디버깅을 어렵게 할 수 있습니다.
- 과도한 예외 처리: 필요 이상의 예외 처리는 코드의 가독성을 떨어뜨릴 수 있습니다.
예제 및 실습 문제
문제 1: 파일 읽기 예외 처리
def read_file(file_path):
try:
with open(file_path, 'r') as file:
content = file.read()
print(content)
except FileNotFoundError:
print("파일을 찾을 수 없습니다.")
except Exception as e:
print(f"예외가 발생했습니다: {e}")
read_file("example.txt")
문제 2: 리스트 인덱스 예외 처리
python코드 복사
def get_element(lst, index):
try:
return lst[index]
except IndexError:
return "인덱스가 범위를 벗어났습니다."
numbers = [1, 2, 3, 4, 5]
print(get_element(numbers, 10)) # 출력: 인덱스가 범위를 벗어났습니다.
문제 3: 숫자 입력 예외 처리
python코드 복사
def safe_input():
try:
return int(input("숫자를 입력하세요: "))
except ValueError:
return "유효한 숫자를 입력하세요."
print(safe_input())
넘파이 (NumPy)
넘파이란?
- 넘파이(NumPy)는 파이썬에서 수치 데이터를 다루기 위한 핵심 라이브러리입니다.
- 넘파이는 대규모 다차원 배열과 행렬을 지원하며, 이들을 효율적으로 조작할 수 있는 다양한 수학 함수를 제공합니다.
- 편의성뿐만 아니라, 속도면에서도 순수 파이썬에 비해 압도적으로 빠르다는 장점이 있습니다.
- Numpy의 핵심이라고 불리는 다차원 행렬 자료구조인 ndarray를 통해 벡터 및 행렬을 사용하는 선형 대수 계산에서 주로 사용됩니다.
주요 특징
- 빠른 연산 속도: 넘파이 배열은 파이썬의 기본 리스트보다 훨씬 빠른 연산 속도를 제공합니다.
- 다차원 배열: 넘파이는 다차원 배열 객체인 ndarray를 제공합니다.
- 벡터화 연산: 복잡한 수학 연산을 단순한 코드로 작성할 수 있습니다.
- 다양한 함수 제공: 수학, 통계, 선형대수 등 다양한 수학 함수를 제공합니다.
넘파이 설치
넘파이는 pip를 사용하여 쉽게 설치할 수 있습니다.
pip install numpy
넘파이 시작하기
넘파이를 사용하기 위해서는 먼저 넘파이를 임포트해야 합니다.
import numpy as np
배열 생성
넘파이 배열은 다양한 방법으로 생성할 수 있습니다.
리스트를 사용하여 배열 생성
import numpy as np
# 리스트를 사용하여 1차원 배열 생성
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1) # 출력: [1 2 3 4 5]
# 리스트를 사용하여 2차원 배열 생성
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2) # 출력: [[1 2 3]
# [4 5 6]]
초기화된 배열 생성
# 모든 요소가 0인 배열 생성
zeros = np.zeros((3, 3))
print(zeros) # 출력: [[0. 0. 0.]
# [0. 0. 0.]
# [0. 0. 0.]]
# 모든 요소가 1인 배열 생성
ones = np.ones((2, 4))
print(ones) # 출력: [[1. 1. 1. 1.]
# [1. 1. 1. 1.]]
# 특정 값으로 초기화된 배열 생성
full = np.full((3, 3), 7)
print(full) # 출력: [[7 7 7]
# [7 7 7]
# [7 7 7]]
# 단위 행렬 생성
identity = np.eye(4)
print(identity) # 출력: [[1. 0. 0. 0.]
# [0. 1. 0. 0.]
# [0. 0. 1. 0.]
# [0. 0. 0. 1.]]
연속된 값 또는 랜덤 값으로 배열 생성
# 연속된 값으로 배열 생성
sequence = np.arange(10)
print(sequence) # 출력: [0 1 2 3 4 5 6 7 8 9]
# 랜덤 값으로 배열 생성
random_arr = np.random.random((3, 3))
print(random_arr) # 출력: 3x3 크기의 랜덤 값 배열
배열 속성
넘파이 배열의 주요 속성을 확인할 수 있습니다.
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.ndim) # 배열의 차원 수 출력: 2
print(arr.shape) # 배열의 형태 출력: (2, 3)
print(arr.size) # 배열의 총 요소 수 출력: 6
print(arr.dtype) # 배열 요소의 자료형 출력: int64
배열 연산
넘파이는 배열 간의 기본 연산을 지원합니다.
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 배열 덧셈
print(a + b) # 출력: [5 7 9]
# 배열 뺄셈
print(a - b) # 출력: [-3 -3 -3]
# 배열 곱셈
print(a * b) # 출력: [ 4 10 18]
# 배열 나눗셈
print(a / b) # 출력: [0.25 0.4 0.5 ]
# 배열 요소별 제곱
print(a ** 2) # 출력: [1 4 9]
배열 인덱싱 및 슬라이싱
넘파이 배열은 파이썬 리스트와 유사하게 인덱싱 및 슬라이싱이 가능합니다.
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 인덱싱
print(arr[0, 2]) # 출력: 3
# 슬라이싱
print(arr[1:, 1:]) # 출력: [[5 6]
# [8 9]]
브로드캐스팅
브로드캐스팅은 서로 다른 크기의 배열 간 연산을 가능하게 합니다.
a = np.array([1, 2, 3])
b = np.array([[4], [5], [6]])
print(a + b)
# 출력: [[5 6 7]
# [6 7 8]
# [7 8 9]]
유용한 함수
넘파이는 다양한 유용한 함수를 제공합니다.
집계 함수
arr = np.array([1, 2, 3, 4, 5])
print(np.sum(arr)) # 배열 요소의 합 출력: 15
print(np.mean(arr)) # 배열 요소의 평균 출력: 3.0
print(np.min(arr)) # 배열 요소의 최솟값 출력: 1
print(np.max(arr)) # 배열 요소의 최댓값 출력: 5
선형대수 함수
mat1 = np.array([[1, 2], [3, 4]])
mat2 = np.array([[5, 6], [7, 8]])
# 행렬 곱
print(np.dot(mat1, mat2))
# 출력: [[19 22]
# [43 50]]
# 행렬 전치
print(np.transpose(mat1))
# 출력: [[1 3]
# [2 4]]
# 역행렬
print(np.linalg.inv(mat1))
# 출력: [[-2. 1. ]
# [ 1.5 -0.5]]
판다스(Pandas)
판다스(Pandas)는 데이터 조작 및 분석을 위한 파이썬 라이브러리로, 특히 데이터프레임(DataFrame)이라는 강력한 자료 구조를 제공하여 데이터를 쉽게 처리하고 분석할 수 있게 해줍니다.
1. 판다스 시작하기
설치
먼저 판다스를 설치해야 합니다. 터미널이나 명령 프롬프트에서 다음 명령어를 실행하세요:
pip install pandas
임포트
판다스를 사용하기 위해 파이썬 코드에 임포트합니다:
import pandas as pd
2. 데이터 구조
판다스는 주로 두 가지 데이터 구조를 사용합니다:
- 시리즈(Series): 1차원 배열
- 데이터프레임(DataFrame): 2차원 테이블
시리즈 (Series)
시리즈란?
- 시리즈는 1차원 배열과 같은 자료 구조로, 데이터의 순차적 리스트를 나타냅니다.
- 각 데이터는 인덱스와 연관되어 있으며, 기본적으로 정수 인덱스를 사용합니다. 하지만 문자열 인덱스도 사용할 수 있습니다.
시리즈 생성
import pandas as pd
# 리스트를 사용하여 시리즈 생성
sr = pd.Series([17000, 18000, 1000, 5000])
print(sr)
# 출력:
# 0 17000
# 1 18000
# 2 1000
# 3 5000
# dtype: int64
# 인덱스를 지정하여 시리즈 생성
sr = pd.Series([17000, 18000, 1000, 5000], index=["피자", "치킨", "콜라", "맥주"])
print(sr)
# 출력:
# 피자 17000
# 치킨 18000
# 콜라 1000
# 맥주 5000
# dtype: int64
시리즈의 값과 인덱스 접근
# 시리즈의 값
print(sr.values) # 출력: [17000 18000 1000 5000]
# 시리즈의 인덱스
print(sr.index) # 출력: Index(['피자', '치킨', '콜라', '맥주'], dtype='object')
데이터프레임 (DataFrame)
데이터프레임이란?
- 데이터프레임은 2차원 테이블 구조를 가지는 데이터 구조로, 행(row)과 열(column)로 구성됩니다.
- 엑셀 스프레드시트나 SQL 테이블과 유사한 구조를 가지며, 다양한 데이터 타입을 저장할 수 있습니다.
- 데이터프레임은 여러 시리즈가 모인 형태로 이해할 수 있습니다.
데이터프레임 생성
# 리스트를 사용하여 데이터프레임 생성
data = [[1, 'Alice', 23], [2, 'Bob', 25], [3, 'Charlie', 22]]
df = pd.DataFrame(data, columns=['ID', 'Name', 'Age'])
print(df)
# 출력:
# ID Name Age
# 0 1 Alice 23
# 1 2 Bob 25
# 2 3 Charlie 22
# 딕셔너리를 사용하여 데이터프레임 생성
data = {'ID': [1, 2, 3], 'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [23, 25, 22]}
df = pd.DataFrame(data)
print(df)
# 출력:
# ID Name Age
# 0 1 Alice 23
# 1 2 Bob 25
# 2 3 Charlie 22
데이터프레임의 속성
print(df.index) # 행 인덱스 출력
# 출력: RangeIndex(start=0, stop=3, step=1)
print(df.columns) # 열 이름 출력
# 출력: Index(['ID', 'Name', 'Age'], dtype='object')
print(df.values) # 값 출력
# 출력:
# [[1 'Alice' 23]
# [2 'Bob' 25]
# [3 'Charlie' 22]]
데이터 조작 및 선택
필터링
데이터프레임에서 조건에 맞는 데이터만 선택할 수 있습니다.
print(df[df['Age'] > 23])
# 출력:
# ID Name Age
# 1 2 Bob 25
데이터 추가
열 추가
새로운 열을 데이터프레임에 추가할 수 있습니다.
df['City'] = ['New York', 'Los Angeles', 'Chicago']
print(df)
# 출력:
# ID Name Age City
# 0 1 Alice 23 New York
# 1 2 Bob 25 Los Angeles
# 2 3 Charlie 22 Chicago
행 추가
새로운 행을 데이터프레임에 추가할 수 있습니다.
new_row = {'ID': 4, 'Name': 'David', 'Age': 24, 'City': 'San Francisco'}
df = df.append(new_row, ignore_index=True)
print(df)
# 출력:
# ID Name Age City
# 0 1 Alice 23 New York
# 1 2 Bob 25 Los Angeles
# 2 3 Charlie 22 Chicago
# 3 4 David 24 San Francisco
데이터 수정
특정 값을 수정할 수 있습니다.
df.loc[0, 'Age'] = 24
print(df)
# 출력:
# ID Name Age City
# 0 1 Alice 24 New York
# 1 2 Bob 25 Los Angeles
# 2 3 Charlie 22 Chicago
# 3 4 David 24 San Francisco
데이터 삭제
열 삭제
특정 열을 삭제할 수 있습니다.
df = df.drop('City', axis=1)
print(df)
# 출력:
# ID Name Age
# 0 1 Alice 24
# 1 2 Bob 25
# 2 3 Charlie 22
# 3 4 David 24
행 삭제
특정 행을 삭제할 수 있습니다.
df = df.drop(0, axis=0)
print(df)
# 출력:
# ID Name Age
# 1 2 Bob 25
# 2 3 Charlie 22
# 3 4 David 24
데이터프레임 결합
concat을 사용한 데이터프레임 결합
여러 데이터프레임을 위아래로 또는 좌우로 결합할 수 있습니다.
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'], 'B': ['B0', 'B1', 'B2']})
df2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'], 'B': ['B3', 'B4', 'B5']})
result = pd.concat([df1, df2])
print(result)
# 출력:
# A B
# 0 A0 B0
# 1 A1 B1
# 2 A2 B2
# 0 A3 B3
# 1 A4 B4
# 2 A5 B5
merge를 사용한 데이터프레임 결합
SQL의 JOIN 연산처럼 두 데이터프레임을 결합할 수 있습니다.
left = pd.DataFrame({'key': ['K0', 'K1', 'K2'], 'A': ['A0', 'A1', 'A2']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K3'], 'B': ['B0', 'B1', 'B3']})
result = pd.merge(left, right, on='key')
print(result)
# 출력:
# key A B
# 0 K0 A0 B0
# 1 K1 A1 B1
그룹화 및 집계
groupby를 사용한 그룹화
데이터를 그룹화하여 요약 통계를 계산할 수 있습니다.
data = {'Team': ['A', 'B', 'A', 'B'], 'Points': [10, 20, 30, 40]}
df = pd.DataFrame(data)
grouped = df.groupby('Team')
print(grouped.sum())
# 출력:
# Points
# Team
# A 40
# B 60
집계 함수
그룹화한 데이터에 대해 다양한 집계 함수를 적용할 수 있습니다.
print(grouped['Points'].mean())
# 출력:
# Team
# A 20.0
# B 30.0
# Name: Points, dtype: float64
print(grouped['Points'].sum())
# 출력:
# Team
# A 40
# B 60
# Name: Points, dtype: int64
print(grouped['Points'].min())
# 출력:
# Team
# A 10
# B 20
# Name: Points, dtype: int64
print(grouped['Points'].max())
# 출력:
# Team
# A 30
# B 40
# Name: Points, dtype: int64
print(grouped['Points'].count())
# 출력:
# Team
# A 2
# B 2
# Name: Points, dtype: int64
결측치 처리
결측치 확인
결측치(NaN)를 확인할 수 있습니다.
df = pd.DataFrame({'A': [1, 2, None], 'B': [4, None, 6], 'C': [None, 8, 9]})
print(df)
# 출력:
# A B C
# 0 1.0 4.0 NaN
# 1 2.0 NaN 8.0
# 2 NaN 6.0 9.0
print(df.isnull())
# 출력:
# A B C
# 0 False False True
# 1 False True False
# 2 True False False
print(df.isnull().sum())
# 출력:
# A 1
# B 1
# C 1
# dtype: int64
결측치 제거
결측치가 포함된 행을 제거할 수 있습니다.
df = df.dropna()
print(df)
# 출력:
# Empty DataFrame
# Columns: [A, B, C]
# Index: []
결측치 대체
결측치를 특정 값으로 대체할 수 있습니다.
df = pd.DataFrame({'A': [1, 2, None], 'B': [4, None, 6], 'C': [None, 8, 9]})
df['A'] = df['A'].fillna(df['A'].mean())
print(df)
# 출력:
# A B C
# 0 1.000000 4.0 NaN
# 1 2.000000 NaN 8.0
# 2 1.500000 6.0 9.0
데이터 정렬
인덱스를 기준으로 정렬
데이터프레임을 인덱스를 기준으로 정렬할 수 있습니다.
df = df.sort_index()
print(df)
# 출력:
# A B C
# 0 1.000000 4.0 NaN
# 1 2.000000 NaN 8.0
# 2 1.500000 6.0 9.0
값을 기준으로 정렬
특정 열의 값을 기준으로 데이터프레임을 정렬할 수 있습니다.
df = df.sort_values(by='A')
print(df)
# 출력:
# A B C
# 0 1.000000 4.0 NaN
# 2 1.500000 6.0 9.0
# 1 2.000000 NaN 8.0
데이터 저장
CSV 파일로 저장
데이터프레임을 CSV 파일로 저장할 수 있습니다.
df.to_csv('output.csv', index=False)
엑셀 파일로 저장
데이터프레임을 엑셀 파일로 저장할 수 있습니다.
df.to_excel('output.xlsx', index=False)