Pandas의 loc와 iloc 사용법 정리
Pandas에서 loc와 iloc은 DataFrame이나 Series에서 특정 데이터나 행, 열을 선택할 때 사용하는 중요한 기능입니다.
- 행/열의 이름(label)로 데이터를 찾을 땐
loc
- 위치를 기반으로 데이터를 찾을 땐
iloc
loc vs iloc
| 구분 | 의미 | 사용하는 값 | 끝 값 포함 여부 |
|---|
loc | label-based indexing (라벨 기준) | 행/열의 이름(label) | ✅ (포함) |
iloc | integer-based indexing (정수 위치 기준) | 정수 인덱스(0, 1, 2, ...) | ❌ (포함 안 함) |
예시
- 다음과 같은 DataFrame이 있다고 가정합니다.
import pandas as pd
df = pd.DataFrame({
"A": ["A0", "A1", "A2"],
"B": ["B0", "B1", "B2"],
"C": ["C0", "C1", "C2"]
}, index=["row1", "row2", "row3"])
A B C
row1 A0 B0 C0
row2 A1 B1 C1
row3 A2 B2 C2
loc (라벨로 선택)
한 행 선택하기
df.loc["row1"]
여러 행, 여러 열 선택하기
df.loc[["row1", "row2"], ["A", "B"]]
범위로 선택하기 (끝 포함)
df.loc["row1":"row2", "A":"B"]
iloc (정수 위치로 선택)
한 행 선택하기
df.iloc[0]
여러 행, 여러 열 선택하기
df.iloc[[0, 1], [0, 1]]
범위로 선택하기 (끝 포함 안 됨)
df.iloc[0:2, 0:2]
⚠️ 주의할 점
loc은 인덱스(행, 열의 이름)로 데이터를 찾으며, 슬라이싱에서 끝이 포함됩니다.
iloc은 0부터 시작하는 정수 위치로 찾으며, 슬라이싱에서 끝이 포함되지 않습니다.
Pandas Accessor
Pandas에서는 Series와 Index에 대해 특정 데이터 타입에 특화된 연산을 벡터화하여 수행할 수 있게 도와주는 Accessor (.str, .dt, .cat 등) 를 제공합니다.
이 Accessor는 마치 데이터 타입 전용 도구상자라고 볼 수 있습니다.
- Accessor는 특정 데이터 타입에 특화된 메서드 집합입니다.
- Pandas의
Series 또는 Index에서만 사용 가능합니다.
- 벡터화된 방식으로 반복문 없이 빠르게 데이터 처리할 수 있습니다.
주요 Accessor 목록
| Accessor | 대상 타입 | 설명 | 사용 예시 |
|---|
.str | 문자열 (object, string) | 문자열 관련 메서드 제공 | s.str.replace(' ', '_') |
.dt | 날짜/시간 (datetime64) | 날짜/시간 정보 추출 및 포맷팅 | s.dt.year, s.dt.day_name() |
.cat | 카테고리 (category) | 카테고리 관리 및 처리 | s.cat.codes, s.cat.remove_unused_categories() |
.sparse | 희소 데이터 (SparseDtype) | 메모리 절약형 희소 데이터 연산 | s.sparse.density |
.flags | Series/DataFrame | 내부 설정값 확인 및 설정 | s.flags.allows_duplicate_labels |
.array | ExtensionArray-backed Series | 내부 배열에 직접 접근 | s.array (예: nullable int, string 등) |
1. 문자열 처리: .str
s = pd.Series(['apple pie', 'banana bread'])
s.str.replace(' ', '_')
문자열 처리 함수 목록
import inspect
df = pd.DataFrame({"data": ["Hello", "World"]})
for name in [name for name, object in inspect.getmembers(df['data'].str) if not name.startswith("_")]:
print(f"- {name}")
- capitalize
- casefold
- cat
- center
- contains
- count
- decode
- encode
- endswith
- extract
- extractall
- find
- findall
- fullmatch
- get
- get_dummies
- index
- isalnum
- isalpha
- isdecimal
- isdigit
- islower
- isnumeric
- isspace
- istitle
- isupper
- join
- len
- ljust
- lower
- lstrip
- match
- normalize
- pad
- partition
- removeprefix
- removesuffix
- repeat
- replace
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- slice
- slice_replace
- split
- startswith
- strip
- swapcase
- title
- translate
- upper
- wrap
- zfill
2. 날짜 처리: .dt
s = pd.Series(pd.to_datetime(['2023-01-01', '2024-03-23']))
s.dt.year
s.dt.day_name()
날짜 처리 함수 목록
import inspect
df = pd.DataFrame({"data": ["2024-03-02", "2024-04-02"]})
df['data'] = pd.to_datetime(df['data'])
for name in [name for name, object in inspect.getmembers(df['data'].dt) if not name.startswith("_")]:
print(f"- {name}")
- as_unit
- ceil
- date
- day
- day_name
- day_of_week
- day_of_year
- dayofweek
- dayofyear
- days_in_month
- daysinmonth
- floor
- freq
- hour
- is_leap_year
- is_month_end
- is_month_start
- is_quarter_end
- is_quarter_start
- is_year_end
- is_year_start
- isocalendar
- microsecond
- minute
- month
- month_name
- nanosecond
- normalize
- quarter
- round
- second
- strftime
- time
- timetz
- to_period
- to_pydatetime
- tz
- tz_convert
- tz_localize
- unit
- weekday
- year
3. 카테고리 처리: .cat
s = pd.Series(['red', 'blue', 'green'], dtype='category')
s.cat.codes
카테고리 처리 함수 목록
import inspect
df = pd.DataFrame({"data": ["a", "b", "c", "a", "c"]}).astype('category')
for name in [name for name, object in inspect.getmembers(df['data'].cat) if not name.startswith("_")]:
print(f"- {name}")
- add_categories
- as_ordered
- as_unordered
- categories
- codes
- ordered
- remove_categories
- remove_unused_categories
- rename_categories
- reorder_categories
- set_categories
4. 희소 데이터: .sparse
s = pd.Series([0, 0, 1, 0, 2], dtype=pd.SparseDtype("int", fill_value=0))
s.sparse.density
5. 플래그: .flags
s = pd.Series([1, 2, 3])
s.flags.allows_duplicate_labels
Pandas 주요 데이터 타입 정리
| 데이터 타입 | dtype 표기 | 예시 | 설명 |
|---|
| 정수 | int64, int32, Int64 등 | 1, 5, 100 | 정수형 숫자 |
| 실수 | float64, float32 등 | 3.14, 0.99 | 소수점 포함 숫자 |
| 복소수(complex) | complex128, complex64 | 1+2j, 3+4j | 복소수형 숫자 |
| 문자열 | object, string | 'hello', '가나다' | 문자열 데이터 |
| 불리언(Boolean) | bool | True, False | 참/거짓 값 |
| 날짜/시간 | datetime64[ns] | '2023-01-01' | 날짜 및 시간 데이터 |
| timedelta | timedelta64[ns] | '2 days', '01:00:00' | 시간의 차이 |
| 카테고리(Category) | category | 'male', 'female' | 범주형 데이터 |
| 희소형(Sparse) | Sparse[int64], Sparse[float] 등 | 대부분 0인 데이터 | 메모리 절약형 데이터 |
1. 기본 정수(int64)
s = pd.Series([1, 2, 3])
s.dtype
2. 실수형(float64)
s = pd.Series([1.1, 2.2, 3.3])
s.dtype
3. 문자열(object 또는 string)
s = pd.Series(['apple', 'banana'])
s.dtype
4. 날짜/시간(datetime64[ns])
s = pd.Series(pd.to_datetime(['2023-01-01', '2024-03-23']))
s.dtype
5. 불리언(bool)
s = pd.Series([True, False, True])
s.dtype
6. 카테고리(category)
s = pd.Series(['small', 'medium', 'large'], dtype='category')
s.dtype
7. 시간 차이(timedelta64[ns])
s = pd.Series(pd.to_timedelta(['1 days', '5 hours']))
s.dtype
8. 복소수(complex)
s = pd.Series([1+2j, 3+4j])
s.dtype
9. 희소형 데이터(Sparse)
s = pd.Series([0, 0, 1, 0, 0], dtype=pd.SparseDtype("int", 0))
s.dtype
pandas 모듈에서 직접 제공하는 pd.to_xxxx 함수들
- 데이터 전처리 단계에서 자주 사용됨.
- 데이터를 올바른 dtype으로 변환할 때 필수적.
- 범용성이 높아 데이터 분석에서 매우 자주 사용됩니다.
이 함수들은 pd. 형태로 직접 호출됩니다. (DataFrame 객체의 메서드와는 별개입니다.)
| 함수 | 용도 | 설명과 예시 |
|---|
pd.to_datetime() | 날짜/시간 타입으로 변환 | 문자열 → datetime 변환
pd.to_datetime(["2024-03-01", "2024-03-02"]) |
pd.to_timedelta() | 시간 차이로 변환 | 문자열 → timedelta 변환
pd.to_timedelta(["2 days", "1 hour"]) |
pd.to_numeric() | 숫자(정수/실수) 타입으로 변환 | 문자열 → 숫자 변환
pd.to_numeric(["1.1", "2.2"]) |
pd.to_pickle() | 객체를 pickle 파일로 저장 | 객체를 직렬화하여 저장
pd.to_pickle(df, "file.pkl") |
1. 날짜 변환 (pd.to_datetime)
pd.to_datetime(['2024-03-02', '2024-03-03'])
2. 시간 차이 변환 (pd.to_timedelta)
pd.to_timedelta(['2 days', '3 hours'])
3. 숫자 변환 (pd.to_numeric)
pd.to_numeric(['1.5', '2.6', '3'])
4. pickle 저장 (pd.to_pickle)
- 빠른 속도로 데이터를 저장하고 로딩할 수 있습니다.
- 객체의 모든 정보(index, dtype, 기타 메타정보 등)가 그대로 유지됩니다.
- 임시 데이터를 빠르게 저장하거나 중간 결과물을 보관할 때 매우 유용합니다.
import pandas as pd
df = pd.DataFrame({'a': [1, 2]})
pd.to_pickle(df, 'df.pkl')
np.squeeze vs ndarray.reshape(-1)
| 기능 | np.squeeze() | reshape(-1) |
|---|
| 작동 방식 | 크기 1인 차원만 제거 | 전체 배열을 1차원으로 평탄화 |
| 유연성 | 특정 axis 지정 가능 (axis=...) | 자동 계산된 1차원 shape으로 변환 |
| shape 예시 1 | (1, 3, 1) → (3,) | (1, 3, 1) → (3,) |
| shape 예시 2 | (2, 3) → 변경 없음 | (2, 3) → (6,) |
| 주 사용 목적 | 불필요한 크기 1 차원 제거 | 데이터를 납작한 배열(flat)로 만들 때 사용 |
np.squeeze(arr)
import numpy as np
arr = np.array([[[10], [20], [30]]])
squeezed = np.squeeze(arr)
print(squeezed)
print(squeezed.shape)
- squeeze()는 (크기 1인 차원만) 제거
- 원소 수는 변하지 않음.
- 원하는 차원을 지정해서 제거할 수도 있음
reshape(-1): 1차원으로 평탄화
arr = np.array([[10], [20], [30]])
flattened = arr.reshape(-1)
print(flattened)
print(flattened.shape)
- reshape(-1)은 1차원으로 평탄화함.
- -1은 “남은 차원은 자동 계산해줘”의 의미.
- 크기가 1이 아닌 차원도 포함해서 전체 구조를 바꿈.