LoginSignup
6
6

More than 3 years have passed since last update.

Pandas DataFrame の任意の場所に列を追加する便利関数

Posted at

Pandas DataFrame の任意の場所に列を追加したい場合は pandas.DataFrame.insert を使うと実現できるが、いくつか不満がある。

  • immutable でない (DataFrame が直接書き換えられてしまう / 破壊的メソッドである / inplace オプションがない)
  • 追加場所をインデックスの数値で指定しなければいけない
    • わかりにくい
    • 「col1 の後に追加」のような指定が難しい
  • Series を入力しても name が無視されるため、別途指定する必要がある
  • DataFrame を入力できない

これらを解決するような便利関数を書いた。

実装

from typing import Union, Optional
import pandas as pd


def insert_columns(
        df: pd.DataFrame,
        data: Union[pd.Series, pd.DataFrame],
        *,
        before: Optional[str] = None,
        after: Optional[str] = None,
        allow_duplicates: bool = False,
        inplace: bool = False,
    ) -> pd.DataFrame:

    if not inplace:
        df = df.copy()

    if not (after is None) ^ (before is None):
        raise ValueError('Specify only "before" or "after"')

    if before:
        loc = df.columns.get_loc(before)
    else:
        loc = df.columns.get_loc(after) + 1

    if type(data) is pd.Series:
        df.insert(loc, data.name, data, allow_duplicates)
    elif type(data) is pd.DataFrame:
        for column in data.columns[::-1]:
            df.insert(loc, column, data[column], allow_duplicates)

    return df
  • before または after にはカラム名を指定する
  • デフォルトでは入力された DataFrame を直接書き換えない
    • inplace=True を指定すれば直接書き換える

使い方

サンプルデータとして sklearn の iris データセットを使う。

from sklearn import datasets

iris = datasets.load_iris()

df = pd.DataFrame(iris.data, columns=iris.feature_names)
target = pd.Series(iris.target_names[iris.target], name='target')
df.head()

image.png

target.head()

image.png

df の sepal width (cm) の後ろに target を追加してみる。

insert_columns(df, target, after='sepal width (cm)')

image.png

この例では Series を追加しているが、DataFrame も指定できる。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6