Pandas apply와 lambda 정리 | 줄 단위 계산을 간단하게 처리하는 방법

Pandas에서 DataFrame을 가공할 때, 각 행이나 각 열에 같은 규칙을 반복 적용해야 하는 경우가 많다.

이럴 때 가장 자주 쓰는 방법이 apply()이고, 여기에 lambda를 붙이면 반복문 없이도 행·열 단위 계산을 짧고 읽기 쉽게 처리할 수 있다. 자료에서도 apply는 줄 단위 규칙을 적용하는 방식으로 설명되고, 날짜별 최고값과 변동성 계산 예시가 이어진다.


apply는 무엇인가

apply()는 DataFrame의 각 행(row) 또는 각 열(column) 에 같은 함수를 적용하는 메서드다.

즉, 이런 상황에 잘 맞는다.

  • 각 행마다 최대값 구하기
  • 각 행마다 최대값과 최소값 차이 구하기
  • 여러 컬럼 값을 바탕으로 새 컬럼 만들기
  • 각 열마다 평균, 합계, 최댓값 계산하기

핵심은 **“같은 규칙이 반복될 때”**다.

규칙이 명확하면 apply()로 깔끔하게 정리할 수 있다. 자료에서도 “줄 단위로 하고자 하는 일에 규칙이 있어야 한다”는 점이 강조된다.


먼저 코드로 보면

예제를 위해 간단한 주가 DataFrame을 만들자.

import pandas as pd

df = pd.DataFrame({
    "시가": [213500, 22000, 200000, 195000, 214500],
    "종가": [210000, 20000, 201000, 22000, 215000],
    "고가": [220000, 23400, 220000, 23000, 225000],
    "저가": [200000, 24400, 225000, 23100, 245000]
}, index=[
    "2026-04-01",
    "2026-04-02",
    "2026-04-03",
    "2026-04-04",
    "2026-04-05"
])

print(df)

apply + lambda 기본 형태

가장 기본 형태는 이렇다.

df.apply(lambda x: 규칙, axis=?)

여기서 중요한 건 두 가지다.

  • x는 각 행 또는 각 열 하나를 의미
  • axis가 행 기준인지 열 기준인지를 결정

axis=0, axis=1 차이

이 부분이 가장 많이 헷갈린다.

axis=0

  • 열(column) 기준
  • 각 컬럼을 하나씩 넘긴다

axis=1

  • 행(row) 기준
  • 각 행을 하나씩 넘긴다

즉,

  • 컬럼별 계산 → axis=0
  • 행별 계산 → axis=1

자료에서도 처음 의도와 다르게 반대 방향으로 적용될 수 있으니, 원하는 방향이 아니면 axis를 바꿔서 맞추는 식으로 설명하고 있다. 특히 날짜별 계산은 행 단위이므로 axis=1을 써야 한다는 흐름이 나온다.


예제 1. 각 행의 최대값 구하기

주가 데이터에서 날짜별 최고값을 구한다고 하면,

각 날짜는 한 행이므로 axis=1을 사용해야 한다.

row_max = df.apply(lambda x: x.max(), axis=1)
print(row_max)

이 코드는 각 행마다

  • 시가
  • 종가
  • 고가
  • 저가

중 가장 큰 값을 찾아준다.

자료에서도 “날짜별로 여러 값 중 최고값 찾기” 예시가 apply + lambda로 설명된다.


예제 2. 각 행의 변동성 계산하기

주가 데이터에서 자주 보는 방식 중 하나가

그날의 최대값 - 최소값을 계산하는 것이다.

volatility = df.apply(lambda x: x.max() - x.min(), axis=1)
print(volatility)

이렇게 하면 날짜별 가격 변동폭을 한 번에 구할 수 있다.

이 패턴이 중요한 이유는, 각 행에서 같은 규칙이 반복되기 때문이다.

  • 최대값 찾기
  • 최소값 찾기
  • 둘의 차이 계산하기

자료에서도 날짜별 변동성을 x.max() - x.min() 형태로 계산하는 흐름이 나온다.


예제 3. 새 컬럼 Gap 만들기

계산 결과를 별도 Series로 두는 데서 끝나지 않고,

기존 DataFrame에 새 컬럼으로 붙이는 경우가 더 많다.

df["Gap"] = df.apply(lambda x: x.max() - x.min(), axis=1)
print(df)

이렇게 하면 기존 데이터에 Gap 컬럼이 추가된다.

실전에서는 이런 방식으로

  • 변동성
  • 평균가
  • 비율
  • 점수
  • 분류 기준

같은 파생 컬럼을 많이 만든다.

자료에서도 계산한 값을 새 컬럼으로 추가하는 흐름이 이어지고, DataFrame은 이런 식의 컬럼 기반 가공이 자연스럽다는 점이 드러난다.


apply가 편한 이유

apply()가 자주 쓰이는 이유는 코드가 짧아서만은 아니다.“무슨 계산을 하는지”가 눈에 바로 보이기 때문이다.

예를 들어 아래 코드는:

df["Gap"] = df.apply(lambda x: x.max() - x.min(), axis=1)

보자마자 이런 뜻으로 읽힌다.

  • 각 행을 돌면서
  • 최대값과 최소값 차이를 계산해서
  • Gap 컬럼에 넣는다

즉, 개별 원소를 어떻게 반복하는지보다

규칙 자체가 코드에 드러난다는 점이 장점이다. 자료에서도 개별 원소 중심이 아니라 “기능 중심으로 코드 작성”하는 방식으로 설명된다.


같은 작업을 for문으로 하면

apply()가 편한 이유를 보려면, 같은 작업을 for문으로 써보면 된다.

방법 1. for문 + iloc/iat

df["Gap"] = 0

for i in range(len(df)):
    values = df.iloc[i, 0:4]
    gap = values.max() - values.min()
    df.iat[i, 4] = gap

print(df)

이 코드는 동작은 같지만, 신경 써야 할 게 많다.

  • 몇 번째 행인지 직접 반복
  • 어떤 컬럼 범위인지 직접 지정
  • 결과를 어느 위치에 넣을지 직접 지정

즉, 계산 규칙보다 접근 방식이 더 많이 보인다.


방법 2. for문 + loc/at

이름 기준으로도 쓸 수 있다.

df["Gap"] = 0

for idx in df.index:
    values = df.loc[idx, ["시가", "종가", "고가", "저가"]]
    gap = values.max() - values.min()
    df.at[idx, "Gap"] = gap

print(df)

이 방식은 iloc/iat보다 읽기 쉽지만, 그래도 여전히 반복 제어를 직접 해야 한다.


apply와 for문 비교

apply가 더 좋은 경우

  • 같은 규칙이 모든 행/열에 반복될 때
  • 코드 길이를 줄이고 싶을 때
  • 계산 의도를 명확하게 보여주고 싶을 때

for문이 더 나은 경우

  • 조건 분기가 복잡할 때
  • 행마다 처리 방식이 많이 다를 때
  • 중간 디버깅이 자주 필요할 때

즉, apply는 반복 규칙이 일정한 가공 작업에 특히 강하다.


구현 관점에서 기억할 포인트

1. axis를 먼저 정해야 한다

apply()에서 가장 중요한 건 방향이다.

  • 열 기준 → axis=0
  • 행 기준 → axis=1

행 단위 계산인데 axis=0으로 쓰면 원하는 결과가 안 나온다. 자료에서도 이 부분을 가장 먼저 구분해서 설명한다.


2. x는 한 개 값이 아니라 한 줄이다

lambda x:에서 x는 숫자 하나가 아니라, 보통 행 하나 또는 열 하나라고 생각해야 한다.

예를 들어 아래 코드에서:

df.apply(lambda x: x.max(), axis=1)

x는 각 날짜의 한 행 전체다.

그래서 x.max(), x.min(), x.mean() 같은 식으로 바로 쓸 수 있다.


3. 새 컬럼 생성과 잘 맞는다

apply() 결과는 Series로 나오기 때문에

그대로 새 컬럼에 넣기 좋다.

df["Gap"] = df.apply(lambda x: x.max() - x.min(), axis=1)

이 패턴은 실전에서 정말 자주 쓴다.


4. 편하지만 무조건 빠른 건 아니다

이건 꼭 같이 알아야 한다.

apply()는 가독성이 좋고 편하지만,큰 DataFrame에서는 성능이 아쉬울 수 있다.

자료에서도 apply는 코드가 편리한 대신 효율성을 무조건 보장하지 않고, 데이터가 커지면 부담이 될 수 있다고 설명한다. 즉, 중소 규모 데이터에서는 유용하지만 대규모 데이터 처리에서는 다른 방식이나 다른 도구를 고려해야 한다는 의미다.


언제 쓰면 좋은가

apply + lambda는 이런 상황에서 특히 좋다.

  • 행별 점수 계산
  • 행별 최대/최소/평균 계산
  • 여러 컬럼을 합쳐 파생 컬럼 만들기
  • 데이터 전처리 규칙을 짧게 표현하고 싶을 때

반대로,

  • 조건 분기가 너무 복잡하거나
  • 데이터가 아주 크거나
  • 완전한 벡터 연산으로 대체 가능한 경우

라면 다른 방식이 더 나을 수 있다.


한 줄 정리

apply + lambda는 DataFrame의 행이나 열에 같은 규칙을 반복 적용할 때, 반복문보다 짧고 읽기 쉽게 가공 코드를 작성하는 방법이다.