python
pandas.loc 마스터하기: 쉬운 데이터 접근을 위한 초보자 가이드

pandas.loc 마스터하기: 쉬운 데이터 접근을 위한 초보자 가이드

MoeNagy Dev

pandas.loc을 이용한 데이터 접근

pandas.loc 소개

pandas.loc은 파이썬의 데이터 조작 및 분석 도구인 pandas 라이브러리에서 강력한 데이터 접근 방법입니다. pandas.loc은 라벨 기반 색인을 기반으로 pandas DataFrame 또는 Series에서 데이터를 선택하고 접근하는 유연하고 직관적인 방법을 제공합니다.

pandas.loc의 주요 목적은 라벨을 사용하여 데이터를 선택하도록 하는 것입니다. 즉, 정수 위치가 아닌 행 및 열 라벨을 기반으로 행, 열 또는 개별 요소에 액세스할 수 있습니다. 이는 실제 세계 데이터셋과 함께 작업할 때 pandas.loc을 특히 유용하게 만듭니다. 실제 데이터는 종종 의미 있는 행 및 열 라벨을 가지기 때문입니다.

pandas.loc은 pandas에서 세 가지 주요 데이터 접근 방법 중 하나이며, pandas.iloc (정수 기반 색인) 및 pandas.ix (라벨 및 정수 기반 색인의 하이브리드)과 함께 사용됩니다. 이러한 방법들의 차이를 이해하는 것은 데이터를 효과적으로 탐색하고 조작하기 위해 중요합니다.

행 및 열 선택

라벨을 기반으로 행 선택

라벨을 기반으로 행을 선택하기 위해서는 다음과 같은 구문을 사용할 수 있습니다:

df.loc[행_라벨]

여기서 행_라벨은 단일 라벨, 라벨의 리스트, 라벨의 슬라이스 또는 논리 배열일 수 있습니다.

예시:

import pandas as pd
 
# 샘플 DataFrame 생성
data = {'이름': ['Alice', 'Bob', 'Charlie', 'David'],
    '나이': [25, 30, 35, 40],
    '도시': ['뉴욕', '런던', '파리', '도쿄']}
df = pd.DataFrame(data)
 
# 라벨을 기반으로 행 선택
print(df.loc['Alice'])
print(df.loc[['Alice', 'Charlie']])
print(df.loc['Alice':'Charlie'])

결과:

이름          Alice
나이              25
도시            뉴욕
Name: Alice, dtype: object
        이름  나이      도시
Alice   25  Alice  New York
Charlie  35  Paris
        이름  나이      도시
Alice   25  Alice  New York
Bob        30    London
Charlie  35  Paris

라벨을 기반으로 열 선택

라벨을 기반으로 열을 선택하기 위해서는 다음과 같은 구문을 사용할 수 있습니다:

df.loc[:, 열_라벨]

여기서 열_라벨은 단일 라벨, 라벨의 리스트, 라벨의 슬라이스 또는 논리 배열일 수 있습니다.

예시:

# 라벨을 기반으로 열 선택
print(df.loc[:, '이름'])
print(df.loc[:, ['이름', '나이']])
print(df.loc[:, '이름':'도시'])

결과:

0    Alice
1      Bob
2  Charlie
3    David
Name: 이름, dtype: object
     이름  나이
0  Alice  25
1    Bob    30
2  Charlie  35
3  David  40
     이름  나이        도시
0  Alice  25  New York
1    Bob  30  London
2  Charlie  35    Paris
3  David  40    Tokyo

단일 값 선택

단일 값을 선택하기 위해서는 다음과 같은 구문을 사용할 수 있습니다:

df.loc[행_라벨, 열_라벨]

예시:

# 단일 값 선택
print(df.loc['Alice', '나이'])

결과:

25

다중 행 및 열 선택

리스트나 슬라이스의 라벨을 전달하여 다중 행 및 열을 동시에 선택할 수 있습니다.

예시:

# 다중 행 및 열 선택
print(df.loc[['Alice', 'Charlie'], ['이름', '도시']])

결과:

        이름        도시
0     Alice  New York
2  Charlie    Paris

조건 선택

조건에 따른 행 필터링

한 개 이상의 조건에 따라 행을 필터링하기 위해 불리언 인덱싱을 사용할 수 있습니다.

예시:

# 조건에 따른 행 필터링
print(df.loc[df['나이'] > 30])

결과:

       이름  나이      도시
2  Charlie  35    Paris
3    David  40    Tokyo

여러 조건 결합

& (그리고) 및 | (또는)와 같은 불리언 연산자를 사용하여 여러 조건을 결합할 수 있습니다.

예시:

# 여러 조건 결합
print(df.loc[(df['나이'] > 30) & (df['도시'] != '뉴욕')])

결과:

       이름  나이      도시
2  Charlie  35    Paris
3    David  40    Tokyo

행 및 열 동시 선택

pandas.loc을 사용하여 행과 열을 동시에 선택할 수 있습니다.

예시:

# 행과 열 동시 선택
print(df.loc[df['나이'] > 30, ['이름', '도시']])

결과:

       이름        도시
2  Charlie      Paris
3    David     Tokyo

누락된 데이터 처리

pandas.loc에서 누락된 값 처리

pandas.loc은 다른 pandas 데이터 접근 방법과 마찬가지로 누락된 값을 처리합니다. 행이나 열에 누락된 값이 포함되어 있는 경우, 선택에 포함됩니다.

예시:

# 누락된 값을 포함하는 DataFrame 생성
data = {'이름': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
        '나이': [25, 30, None, 40, 35],
        '도시': ['뉴욕', '런던', '파리', None, '도쿄']}
df = pd.DataFrame(data)
 
# 누락된 값이 포함된 행과 열 선택
print(df.loc[:, ['나이', '도시']])

결과:

     나이        도시
0   25.0  뉴욕
1   30.0  런던
2   NaN  파리
3   40.0  NaN
4   35.0  도쿄

누락된 값 대체

pandas.loc을 사용하여 DataFrame 내 누락된 값을 대체할 수 있습니다.

예시:

# 누락된 값을 특정 값으로 대체
df.loc[:, '나이'] = df['나이'].fillna(0)
df.loc[:, '도시'] = df['도시'].fillna('Unknown')
print(df)

결과:

       이름  나이        도시
0     Alice   25  뉴욕
1       Bob   30  런던
2   Charlie    0  파리
3     David   40  Unknown
4       Eve   35  도쿄

누락된 데이터 보간하기

다른 행의 값에 기반하여 누락된 값을 보간하기 위해 pandas.loc을 사용할 수도 있습니다.

예시:

# 누락된 값 보간
df['나이'] = df['나이'].interpolate()
print(df.loc[:, '나이'])

결과:

0    25.0
1    30.0
2    35.0

고급 색인

불리언 배열을 사용하여 선택하기

특정 조건에 따라 행과 열을 선택하기 위해 불리언 배열을 사용할 수 있습니다.

예시:

# 선택을 위해 불리언 배열 사용
bool_mask = (df['Age'] > 30) & (df['City'] != '뉴욕')
print(df.loc[bool_mask, ['Name', 'Age', 'City']])

결과:

       Name  Age        City
2   Charlie 35.0      파리
3     David 40.0     알 수 없음
4       Eve 35.0     도쿄

정수 위치를 기반으로 선택하기

pandas.loc는 주로 레이블 기반 색인을 위한 것이지만, pandas.iloc과 결합하여 정수 기반 색인도 사용할 수 있습니다.

예시:

# 레이블 기반과 정수 기반 색인 결합
print(df.loc[0, 'Name'])
print(df.loc[1:3, 'Name':'City'])

결과:

Alice
   Name  Age        City
1   Bob   30    런던
2  Charlie 35.0      파리
3   David 40.0     알 수 없음

다양한 색인 기법 결합하기

레이블 기반, 정수 기반 및 불리언 색인과 같은 다양한 색인 기법을 결합하여 복잡한 선택을 만들 수 있습니다.

예시:

# 여러 색인 기법 결합
print(df.loc[bool_mask, df.columns[::2]])

결과:

       Name        City
2   Charlie      파리
3     David     알 수 없음
4       Eve     도쿄

데이터 수정

행과 열에 값을 할당하기

pandas.loc을 사용하여 DataFrame의 특정 행과 열에 값을 할당할 수 있습니다.

예시:

# 행과 열에 값을 할당
df.loc['Alice', 'Age'] = 26
df.loc[:, 'City'] = '샌프란시스코'
print(df)

결과:

       Name  Age           City
0     Alice   26  샌프란시스코
1       Bob   30  샌프란시스코
2   Charlie   35  샌프란시스코
3     David   40  샌프란시스코
4       Eve   35  샌프란시스코

기존 데이터 업데이트하기

pandas.loc를 사용하여 DataFrame의 기존 데이터를 업데이트할 수도 있습니다.

예시:

# 기존 데이터 업데이트
df.loc[df['Name'] == 'Bob', 'Age'] = 31
print(df)

결과:

       Name  Age           City
0     Alice   26  샌프란시스코
1       Bob   31  샌프란시스코
2   Charlie   35  샌프란시스코
3     David   40  샌프란시스코
4       Eve   35  샌프란시스코

새 데이터 추가하기

pandas.loc은 주로 데이터 선택에 사용되지만, DataFrame에 새로운 행을 추가하는 데에도 사용할 수 있습니다.

예시:

# 새 데이터 추가
new_row = pd.Series({'Name': 'Frank', 'Age': 28, 'City': '로스앤젤레스'})
df.loc[len(df)] = new_row
print(df)

결과:

       Name  Age           City
0     Alice   26  샌프란시스코
1       Bob   31  샌프란시스코
2   Charlie   35  샌프란시스코
3     David   40  샌프란시스코
4       Eve   35  샌프란시스코
5      Frank   28  로스앤젤레스

MultiIndex로 작업하기

MultiIndex DataFrame에서 데이터 선택하기

MultiIndex가 있는 DataFrame에서는 계층적인 인덱스를 기반으로 데이터를 선택하기 위해 pandas.loc를 사용할 수 있습니다.

예시:

# MultiIndex DataFrame 생성
index = pd.MultiIndex.from_tuples([('A', 'X'), ('A', 'Y'), ('B', 'X'), ('B', 'Y')],
                                 names=['Group', 'Subgroup'])
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=index)
 
# MultiIndex DataFrame에서 데이터 선택하기
print(df.loc[('A', 'Y')])
print(df.loc[('B', :)])

결과:

Value    20
Name: ('A', 'Y'), dtype: int64
           Value
Group Subgroup  
B     X        30
      Y        40

MultiIndex에서 조건에 따른 선택

pandas.loc을 사용하여 MultiIndex DataFrame에서 조건부 선택도 가능합니다.

예시:

# MultiIndex에서 조건에 따른 선택
print(df.loc[('A', 'X'), 'Value'])
print(df.loc[df['Value'] > 25])

결과:

10
           Value
Group Subgroup  
B     X        30
      Y        40

MultiIndex DataFrame에서 데이터 수정하기

pandas.loc은 MultiIndex DataFrame에서 데이터 수정에도 사용할 수 있습니다.

예시:

# MultiIndex DataFrame에서 데이터 수정
df.loc[('B', 'Y'), 'Value'] = 45
print(df)

결과:

                Value
Group Subgroup       
A      X           10
       Y           20
B      X           30
       Y           45

성능 최적화

pandas.loc은 강력한 도구이지만, 성능 특성을 이해하고 사용 방법을 최적화하는 것이 중요합니다.

pandas.loc의 성능 특성 이해하기

레이블 기반 색인을 위한 pandas.loc은 일반적으로 pandas.iloc보다 빠르며, 레이블로 데이터에 직접 액세스할 수 있기 때문입니다. 그러나 대용량 데이터나 복잡한 작업의 경우에는 여전히 불리언 색인 또는 기타 메서드보다 pandas.loc이 더 느릴 수 있습니다.

파일과 작업하기

파일 작업은 많은 프로그래밍 작업의 필수적인 부분입니다. Python은 시스템에서 파일과 상호작용하기 위한 간단하고 직관적인 방법을 제공합니다.

파일 열기와 닫기

파일을 열기 위해 내장 open() 함수를 사용할 수 있습니다. open() 함수는 파일 경로와 파일을 열기 위한 모드 두 개의 인수를 사용합니다.

file = open('example.txt', 'r')

모드는 다음 중 하나일 수 있습니다:

  • 'r': 읽기 모드 (기본값)
  • 'w': 쓰기 모드 (기존 내용 덮어씀)
  • 'a': 추가 모드 (파일 끝에 내용 추가)
  • 'x': 배타적 생성 모드 (새 파일 생성, 파일이 이미 존재하는 경우 실패)

파일을 사용한 작업을 마치면 close() 메서드를 사용하여 파일을 닫는 것이 중요합니다:

file.close()

파일 읽기와 쓰기

파일 개체가 준비되면 다양한 방법으로 파일에서 읽거나 파일에 쓸 수 있습니다:

# 파일 전체 읽기
file = open('example.txt', 'r')
content = file.read()
print(content)
file.close()
 
# 한 줄씩 읽기
file = open('example.txt', 'r')
for line in file:
    print(line.strip())
file.close()
 
# 파일에 쓰기
file = open('example.txt', 'w')

file.write('This is a new line.\n')

file.write('This is another line.')

file.close()

파일을 열고 쓰기 위해서는 open() 함수를 사용하고, write() 메서드를 통해 데이터를 파일에 쓸 수 있습니다. 마지막으로 close() 메서드를 사용하여 파일을 닫아주어야 합니다.

### 컨텍스트 관리자 (`with` 문장)

파일을 열고 닫는 과정을 단순화하기 위해서는, 컨텍스트 관리자로서 작동하는 `with` 문장을 사용할 수 있습니다. 이를 통해 예외가 발생하더라도 파일이 제대로 닫히도록 할 수 있습니다.

```python
with open('example.txt', 'r') as file:
    content = file.read()
    print(content)

모듈과 패키지 작업

파이썬의 모듈화된 설계를 통해 코드를 재사용 가능한 구성 요소인 모듈로 구성할 수 있습니다. 모듈은 가져와서 파이썬 스크립트에서 사용할 수 있습니다.

모듈 가져오기

파이썬 스크립트에서 모듈을 사용하기 위해서는 import 문을 사용할 수 있습니다. 모듈 전체를 가져오거나, 모듈에서 특정 함수나 변수를 가져올 수 있습니다.

# 모듈 전체 가져오기
import math
result = math.sqrt(16)
print(result)  # 출력: 4.0
 
# 특정 함수 가져오기
from math import sqrt, pi
result = sqrt(16)
print(result)  # 출력: 4.0
print(pi)  # 출력: 3.141592653589793
 
# 별칭(alias)으로 가져오기
import math as m
result = m.sqrt(16)
print(result)  # 출력: 4.0

모듈 생성하기

파이썬 코드를 .py 파일에 넣어서 직접 모듈을 생성할 수 있습니다. 파일 이름이 모듈 이름이 되며, 이제 모듈을 다른 코드의 일부로 가져올 수 있습니다.

# my_module.py
def greet(name):
    print(f"안녕하세요, {name}!")
 
# 모듈 사용하기
import my_module
my_module.greet("Alice")  # 출력: 안녕하세요, Alice!

패키지

패키지는 모듈을 구성하고 조직화하기 위한 방법입니다. 패키지는 모듈의 컬렉션으로, 관련된 모듈을 함께 그룹화할 수 있습니다.

패키지를 생성하려면 디렉토리를 만들고, 모듈 파일을 내부에 넣어야 합니다. 또한, 패키지 디렉토리에 __init__.py라는 특수 파일을 포함해야 합니다.

my_package/
    __init__.py
    module1.py
    module2.py

이제 점 표기법(dot notation)을 사용하여 패키지에서 모듈을 가져올 수 있습니다:

import my_package.module1
my_package.module1.module1의_함수()
 
from my_package import module2
module2.module2의_함수()

예외 처리하기

예외는 코드에서 예기치 않거나 오류가 발생할 수 있는 상황을 처리하는 방법입니다. 파이썬은 내장 예외 처리 메커니즘을 제공하여 이러한 상황을 예측하고 우아하게 처리할 수 있도록 합니다.

예외 발생하기

raise 문을 사용하여 예외를 발생시킬 수 있습니다. 이는 특정 조건이 발생했음을 알리고 싶을 때 유용합니다.

raise ValueError("잘못된 입력 값")

예외 처리하기

try-except 블록을 사용하여 코드 내에서 예외를 처리할 수 있습니다. try 블록 내에서 예외가 발생하면 해당하는 except 블록이 실행됩니다.

try:
    result = 10 / 0
except ZeroDivisionError:
    print("오류: 0으로 나눌 수 없음")

동일한 except 블록에서 여러 예외를 처리할 수도 있습니다:

try:
    result = int("abc")
except (ValueError, TypeError):
    print("오류: 잘못된 입력")

사용자 정의 예외

내장 Exception 클래스나 그 하위 클래스에서 상속받은 새로운 예외 클래스를 정의함으로써 사용자 정의 예외를 만들 수 있습니다.

class CustomException(Exception):
    pass
 
raise CustomException("이것은 사용자 정의 예외입니다")

finally

finally 절은 예외가 발생하든 발생하지 않든 상관없이 특정 코드 블록을 실행하도록 하는 데 사용됩니다. 이는 파일을 닫는 등의 리소스 정리에 자주 사용됩니다.

try:
    file = open("example.txt", "r")
    content = file.read()
    print(content)
except FileNotFoundError:
    print("오류: 파일을 찾을 수 없음")
finally:
    file.close()

객체지향 프로그래밍 (OOP) 사용하기

파이썬은 절차적 프로그래밍과 객체지향 프로그래밍 (OOP) 스타일을 모두 지원하는 다중 패러다임 언어입니다. OOP는 코드를 조직화하고 구조화하는 강력한 방법입니다.

클래스와 객체

OOP에서는 클래스를 객체를 생성하는 청사진으로 정의합니다. 객체는 이러한 클래스의 인스턴스이며, 자체의 속성과 메서드를 갖습니다.

class Car:
    def __init__(self, make, model):
        self.make = make
        self.model = model
 
    def start(self):
        print(f"{self.make} {self.model}를 시작합니다.")
 
# 객체 생성하기
my_car = Car("Toyota", "Corolla")
my_car.start()  # 출력: Toyota Corolla를 시작합니다.

상속

상속은 기존 클래스를 기반으로 새로운 클래스를 생성하는 방법입니다. 새로운 클래스(자식 클래스)는 기존 클래스(부모 클래스)의 속성과 메서드를 상속받습니다.

class ElectricCar(Car):
    def __init__(self, make, model, battery_capacity):
        super().__init__(make, model)
        self.battery_capacity = battery_capacity
 
    def charge(self):
        print(f"{self.make} {self.model}{self.battery_capacity}kWh 배터리로 충전합니다.")
 
# 자식 클래스의 객체 생성하기
my_electric_car = ElectricCar("Tesla", "Model S", 100)
my_electric_car.start()  # 부모 클래스에서 상속받은 메서드
my_electric_car.charge()  # 자식 클래스에서 정의한 메서드

다형성

다형성은 서로 다른 클래스의 객체를 공통된 슈퍼클래스 객체로 다룰 수 있는 것을 의미합니다. 이는 대개 메서드 오버라이딩을 통해 달성됩니다.

class Motorcycle:
    def start(self):
        print("오토바이를 가동합니다.")
 
class Bicycle:
    def start(self):
        print("자전거를 출발합니다.")
 
# 다형성의 예시
vehicles = [Motorcycle(), Bicycle()]
for vehicle in vehicles:
    vehicle.start()

캡슐화

캡슐화는 데이터와 메서드를 클래스라는 단일 단위로 묶고 외부에는 내부 구현 세부 사항을 숨기는 개념입니다. 이는 public, private, protected와 같은 접근 제한자를 통해 구현됩니다.

class BankAccount:
 
    class BankAccount:
        def __init__(self, owner, balance):
            self.__owner = owner  # 개인 속성
            self.__balance = balance  # 개인 속성
 
        def deposit(self, amount):
            self.__balance += amount
 
        def withdraw(self, amount):
            if amount <= self.__balance:
                self.__balance -= amount
            else:
                print("잔액이 부족합니다.")
 
        def get_balance(self):
            return self.__balance
 
    # BankAccount 클래스 사용하기
    account = BankAccount("Alice", 1000)
    account.deposit(500)
    print(account.get_balance())  # 출력: 1500
    account.__balance = 0  # 캡슐화 때문에 동작하지 않습니다.
 

결론

이 포괄적인 Python 튜토리얼에서는 파일과 모듈 작업부터 객체 지향 프로그래밍의 기본 원리를 다루는 다양한 주제를 다뤘습니다. 이제 이러한 주요 개념에 대해 튼튼한 이해를 갖추었으며, 숙련된 Python 프로그래머가 되기 위한 길에 꽤 진행된 상태입니다.

기억해야 할 것은 Python 기술을 향상시키는 가장 좋은 방법은 실습, 실험 및 계속해서 학습하는 것입니다. 더 고급 주제를 탐구하고 개인 프로젝트에 참여하며 활기찬 Python 커뮤니티와 상호작용하세요. 헌신과 끈기를 가지고, 복잡한 문제를 해결하고 놀라운 애플리케이션을 만들기 위해 Python의 힘을 잘 활용할 수 있을 것입니다.

즐거운 코딩하세요!

MoeNagy Dev