API · Pandas

Pandas DataFrame DataFrame.transpose() 함수

Pandas DataFrame transpose() 함수는 DataFrame의 행을 열로 변경하거나 그 반대로 변경합니다.

이 페이지의 내용

DataFrame.transpose()를 사용하면 pandas DataFrame의 행과 열을 서로 바꿀 수 있습니다. 반환된 DataFrame에서는 원래 행 레이블이 열 레이블이 되고, 원래 열 레이블이 행 레이블이 됩니다. 이 가이드의 예제는 pandas 3.1에서 실행되며, 인수 없는 호출 외에도 T 바로 가기, 숫자와 텍스트가 섞인 경우 데이터 형식에 생기는 변화, 결과가 원본과 메모리를 공유하는 방식을 다룹니다.

DataFrame.transpose() 구문

전치할 객체에서 메서드를 호출합니다: df.transpose(). 전치된 DataFrame이 반환되며, 원래 객체는 df로 계속 사용할 수 있습니다.

import pandas as pd

transposed = dataframe.transpose()

서명은 *args와 copy 키워드도 받지만, 둘 다 NumPy API 및 이전 pandas 코드와의 호환성을 위해 남아 있는 것입니다. 일반적인 호출에서는 어느 쪽도 도움이 되지 않습니다. pandas는 축 위치를 받지 않으며(하나를 전달하면 어떻게 되는지는 아래 오류 섹션에서 확인할 수 있습니다), pandas 3에서는 Copy-on-Write가 데이터 복제 시점을 이미 결정하므로 copy가 사용 중단되었습니다.

예제: DataFrame.transpose()로 DataFrame 전치하기

이 예제에서는 학생 이름, 출석 여부, 점수가 담긴 작은 표를 만듭니다. 메서드를 호출하면 원래 각 열이 결과의 한 행이 되고, 원래 인덱스 레이블은 각각 열이 됩니다.

import pandas as pd

dataframe = pd.DataFrame(
    {
        "Attendance": [60, 100, 80, 78, 95],
        "Name": ["Olivia", "John", "Laura", "Ben", "Kevin"],
        "Obtained Marks": [90, 75, 82, 64, 45],
    }
)

transposed = dataframe.transpose()
print(transposed)

출력:

                     0     1      2    3      4
Attendance          60   100     80   78     95
Name            Olivia  John  Laura  Ben  Kevin
Obtained Marks      90    75     82   64     45

레이블을 보면 행과 열이 바뀐 방향을 쉽게 확인할 수 있습니다. 결과에서 Attendance, Name, Obtained Marks는 행 레이블이고, 0부터 4까지는 열 레이블입니다.

동일한 데이터 형식의 DataFrame 전치하기

모든 열에 정수가 들어 있으면 입력의 값 형식이 동일합니다. 이를 전치한 뒤 원본과 결과의 열 dtype을 모두 확인하면 현재 pandas 환경에서 이 예제가 어떻게 표현되는지 살펴볼 수 있습니다.

import pandas as pd

dataframe = pd.DataFrame(
    {
        "A": [6, 20, 80, 78, 95],
        "B": [60, 50, 7, 67, 54],
    }
)

transposed = dataframe.transpose()
print("Original values:")
print(dataframe)
print("Transposed values:")
print(transposed)
print("Original dtypes:")
print(dataframe.dtypes)
print("Transposed dtypes:")
print(transposed.dtypes)

출력:

Original values:
    A   B
0   6  60
1  20  50
2  80   7
3  78  67
4  95  54
Transposed values:
    0   1   2   3   4
A   6  20  80  78  95
B  60  50   7  67  54
Original dtypes:
A    int64
B    int64
dtype: object
Transposed dtypes:
0    int64
1    int64
2    int64
3    int64
4    int64
dtype: object

이 입력에는 0부터 4까지 레이블이 붙은 행 다섯 개와 A, B 두 열이 있으므로 결과는 행 두 개와 열 다섯 개가 됩니다. 모든 입력 열에 정수가 들어 있으므로 전치된 열은 dtype int64를 유지합니다. DataFrame의 모든 열이 하나의 dtype을 공유하면 전치된 DataFrame의 열도 그 dtype을 유지합니다. 다음 예제에서는 열이 dtype을 공유하지 않을 때 무엇이 달라지는지 보여 줍니다.

데이터 형식이 혼합된 DataFrame 전치하기

DataFrame의 열마다 데이터 형식이 다를 수 있습니다. 이 예제에서는 두 열에 숫자가, 한 열에 이름이 들어 있습니다. 코드에서 연산 전후의 값과 dtype을 확인하여 이 입력의 결과를 살펴볼 수 있습니다.

import pandas as pd

dataframe = pd.DataFrame(
    {
        "Attendance": [60, 100, 80, 78, 95],
        "Name": ["Olivia", "John", "Laura", "Ben", "Kevin"],
        "Obtained Marks": [90, 75, 82, 64, 45],
    }
)

transposed = dataframe.transpose()
print("Original values:")
print(dataframe)
print("Transposed values:")
print(transposed)
print("Original dtypes:")
print(dataframe.dtypes)
print("Transposed dtypes:")
print(transposed.dtypes)

출력:

Original values:
   Attendance    Name  Obtained Marks
0          60  Olivia              90
1         100    John              75
2          80   Laura              82
3          78     Ben              64
4          95   Kevin              45
Transposed values:
                     0     1      2    3      4
Attendance          60   100     80   78     95
Name            Olivia  John  Laura  Ben  Kevin
Obtained Marks      90    75     82   64     45
Original dtypes:
Attendance        int64
Name                str
Obtained Marks    int64
dtype: object
Transposed dtypes:
0    object
1    object
2    object
3    object
4    object
dtype: object

값 자체는 변하지 않고 이동하지만, dtype을 비교해 보세요. 전치된 DataFrame의 모든 열은 숫자만 들어 있는 열까지 포함해 dtype이 object가 됩니다. 이제 각 열은 두 정수 열과 Name 열의 값을 함께 담고 있으며, 이 모두를 담을 수 있는 dtype은 object뿐입니다. 숫자는 그대로 남아 있지만 int64 값이 아닌 일반적인 Python 객체로 저장됩니다.

혼합 전치로 숫자가 객체가 될 때

이 dtype 손실은 단순한 외형 문제가 아닙니다. 전치된 DataFrame 전체에 대한 산술 연산은 이제 Name 행에 저장된 문자열에 닿아 실패합니다:

import pandas as pd

dataframe = pd.DataFrame(
    {
        "Attendance": [60, 100, 80, 78, 95],
        "Name": ["Olivia", "John", "Laura", "Ben", "Kevin"],
        "Obtained Marks": [90, 75, 82, 64, 45],
    }
)

transposed = dataframe.transpose()
print(transposed + 1)

출력:

TypeError: can only concatenate str (not "int") to str

다시 전치하면 원래 배치는 복원되지만 원래 dtype은 복원되지 않습니다. 복원된 DataFrame은 모든 열에서 object를 유지합니다. 다시 실제 숫자로 작업하려면 숫자가 되어야 하는 행을 astype()으로 변환하세요:

import pandas as pd

dataframe = pd.DataFrame(
    {
        "Attendance": [60, 100, 80, 78, 95],
        "Name": ["Olivia", "John", "Laura", "Ben", "Kevin"],
        "Obtained Marks": [90, 75, 82, 64, 45],
    }
)

transposed = dataframe.transpose()
restored = transposed.transpose()
print("Dtypes after transposing back:")
print(restored.dtypes)

numeric_rows = transposed.loc[["Attendance", "Obtained Marks"]].astype(int)
print("Dtypes of the recovered numeric rows:")
print(numeric_rows.dtypes)

출력:

Dtypes after transposing back:
Attendance        object
Name              object
Obtained Marks    object
dtype: object
Dtypes of the recovered numeric rows:
0    int64
1    int64
2    int64
3    int64
4    int64
dtype: object

이 변환은 숫자 행 두 개만 선택합니다. Name 행을 포함하면 astype(int)가 이름에서 실패하므로 텍스트 행은 선택에서 제외하세요.

T 바로 가기로 전치하기

T 속성은 인수 없는 호출의 바로 가기이며 같은 DataFrame을 반환합니다. 정사각형이 아닌 DataFrame에서는 형태만 봐도 교환을 한눈에 확인할 수 있습니다. 행 다섯 개와 열 두 개가 행 두 개와 열 다섯 개가 됩니다. 두 번 전치하면 원본으로 돌아오며, 이 동종 입력에서는 equals()를 통해 값과 dtype이 모두 왕복 후에도 유지됨을 확인할 수 있습니다. 위의 혼합 예제와는 다른 점입니다.

import pandas as pd

dataframe = pd.DataFrame(
    {
        "A": [6, 20, 80, 78, 95],
        "B": [60, 50, 7, 67, 54],
    }
)

print("Original shape:", dataframe.shape)
print("Transposed shape:", dataframe.T.shape)
print("T matches transpose():", dataframe.T.equals(dataframe.transpose()))
print("Transposing twice restores the original:", dataframe.T.T.equals(dataframe))

출력:

Original shape: (5, 2)
Transposed shape: (2, 5)
T matches transpose(): True
Transposing twice restores the original: True

전치된 DataFrame이 원본과 메모리를 공유하는 방식

전치된 DataFrame은 데이터의 독립적인 복사본이 아닙니다. 기본적으로 원본과 메모리를 공유하는 뷰이며, numpy.shares_memory()로 확인할 수 있습니다:

import numpy as np
import pandas as pd

dataframe = pd.DataFrame(
    {
        "A": [6, 20, 80, 78, 95],
        "B": [60, 50, 7, 67, 54],
    }
)

transposed = dataframe.transpose()
print("Shares memory with the original:", np.shares_memory(transposed, dataframe))

transposed.iloc[0, 0] = 999
print("Value in the transposed frame:", transposed.loc["A", 0])
print("Value in the original frame:", dataframe.loc[0, "A"])

출력:

Shares memory with the original: True
Value in the transposed frame: 999
Value in the original frame: 6

메모리를 공유한다고 해서 편집 내용이 원본으로 새어 나가지는 않습니다. pandas 3.0부터 항상 활성화된 Copy-on-Write는 첫 쓰기 시점에 영향을 받는 데이터를 복사하므로, 위 할당은 전치된 DataFrame만 변경하고 원본은 값을 유지합니다. 처음부터 완전히 독립된 DataFrame이 필요하면 결과에 .copy()를 호출하세요.

오류 및 경계 사례

서명의 *args는 NumPy 습관을 떠올리게 하지만, pandas는 DataFrame의 두 축을 항상 서로 바꾸며 축 순열을 받지 않습니다:

import pandas as pd

dataframe = pd.DataFrame({"A": [1, 2], "B": [3, 4]})
print(dataframe.transpose(1))

출력:

ValueError: the 'axes' parameter is not supported in the pandas implementation of transpose()

(1, 0) 같은 튜플도 같은 ValueError로 실패합니다. 반면 퇴화한 형태는 오류가 아니라 유효한 입력입니다:

import pandas as pd

empty = pd.DataFrame(columns=["A", "B"])
print("Original shape:", empty.shape)
print("Transposed shape:", empty.transpose().shape)

single_row = pd.DataFrame({"A": [1], "B": [2], "C": [3]})
print(single_row.transpose())

출력:

Original shape: (0, 2)
Transposed shape: (2, 0)
   0
A  1
B  2
C  3

열만 있고 행이 없는 DataFrame은 형태 (0, 2)가 (2, 0)으로 바뀌고, 행 하나짜리 DataFrame은 원래 열 레이블을 인덱스로 갖는 열 하나가 됩니다.