max() / min() 이 값 을 반환한다면, idxmax() / idxmin() 은 그 값이 있는 index 라벨 을 반환한다. “MAX 인 행의 다른 컬럼도 가져오기” 가 전형적인 사용 상황.
사용 상황
상황
패턴
최고 점수 학생 이름
df.loc[df['score'].idxmax(), 'name']
부서별 최고 연봉자 전체 행
df.loc[df.groupby('dept')['salary'].idxmax()]
시계열 최고점 날짜
ts.idxmax() (Timestamp 반환)
가장 빈번한 카테고리 (단건)
df['city'].value_counts().idxmax()
동작 원리
flowchart LR
A["Series 또는 DataFrame 컬럼"] --> B["max()"]
A --> C["idxmax()"]
B --> D["최댓값 숫자 반환"]
C --> E["최댓값 위치의 index 라벨 반환"]
E --> F["df.loc 에 바로 사용 가능"]
Series 기본 사용
python
import pandas as pds = pd.Series([10, 50, 30, 20], index=['a', 'b', 'c', 'd'])print('max value:', s.max())print('idxmax :', s.idxmax())print('min value:', s.min())print('idxmin :', s.idxmin())print()# idxmax 라벨로 바로 loc 접근print('idxmax 위치 값:', s.loc[s.idxmax()])
결과
max value: 50idxmax : bmin value: 10idxmin : aidxmax 위치 값: 50
index 라벨 'b' 가 최댓값(50) 의 위치.
DataFrame.idxmax : axis 방향
df.idxmax() # 각 컬럼에서 최댓값을 가진 행 index (axis=0, 기본)df.idxmax(axis=1) # 각 행에서 최댓값을 가진 컬럼 이름 (axis=1)df.idxmin() # 최솟값 버전df.idxmin(axis=1)
python
import pandas as pddf = pd.DataFrame({ 'math': [90, 80, 70], 'eng': [85, 95, 75], 'sci': [95, 70, 80],}, index=['Alice', 'Bob', 'Charlie'])print('--- 각 과목 최고점 학생 ---')print(df.idxmax())print()print('--- 각 학생 최고 과목 ---')print(df.idxmax(axis=1))
결과
--- 각 과목 최고점 학생 ---math Aliceeng Bobsci Alicedtype: object--- 각 학생 최고 과목 ---Alice sciBob engCharlie scidtype: object
최댓값 행 전체 가져오기
# salary 가 가장 높은 직원의 모든 정보df.loc[df['salary'].idxmax()]# salary 가 가장 낮은 직원의 모든 정보df.loc[df['salary'].idxmin()]# 특정 컬럼만 꺼내기df.loc[df['salary'].idxmax(), 'name']df.loc[df['salary'].idxmax(), ['name', 'dept']]
groupby + idxmax (그룹별 최대 행)
SQL 에서 GROUP BY + MAX 후 해당 행 전체를 가져오는 전형적인 패턴.
# 각 부서의 최고 연봉자 행 전체df.loc[df.groupby('dept')['salary'].idxmax()]
python
import pandas as pddata = { 'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'], 'dept': ['eng', 'eng', 'mkt', 'mkt', 'eng'], 'salary': [9000, 7500, 6000, 8000, 8500],}df = pd.DataFrame(data)idx = df.groupby('dept')['salary'].idxmax()print('각 부서 최고 연봉자 index:')print(idx)print()result = df.loc[idx]print('각 부서 최고 연봉자 전체 정보:')print(result)
결과
각 부서 최고 연봉자 index:depteng 0mkt 3Name: salary, dtype: int64각 부서 최고 연봉자 전체 정보: name dept salary0 Alice eng 90003 David mkt 8000
flowchart TD
A["df"] --> B["groupby('dept')"]
B --> C["idxmax() on salary"]
C --> D["dept 별 최고 salary 행의 index 라벨"]
D --> E["df.loc 적용"]
E --> F["dept 별 최고 연봉자 행 전체"]
이 패턴은 SQL 의 아래 쿼리와 동일하다:
SELECT * FROM employeesWHERE (dept, salary) IN ( SELECT dept, MAX(salary) FROM employees GROUP BY dept)
value_counts + idxmax
# 가장 자주 등장하는 값 (한 줄)most_common = df['city'].value_counts().idxmax()# mode().iloc[0] 과 동일, 둘 다 유효most_common2 = df['city'].mode().iloc[0]
NaN 처리
import numpy as nps = pd.Series([1.0, np.nan, 3.0, np.nan])s.idxmax() # NaN skip → 2 (값 3.0 의 위치)s.idxmax(skipna=False) # NaN 포함 → NaN 반환
for col in df.select_dtypes('number').columns: idx = df[col].idxmax() print(f'{col}: 최대={df[col].max()}, 행={idx}, 이름={df.loc[idx, "name"]}')
함정
1. 모두 NaN 이면 ValueError
pd.Series([None, None]).idxmax()# ValueError: attempt to get argmax of an empty sequence# 방어 코드def safe_idxmax(s): valid = s.dropna() return valid.idxmax() if not valid.empty else None
💬 댓글