3
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pandas.DataFrame.applyを使って、DataFrameに複数列を一度に追加したい

Last updated at Posted at 2021-04-14

TL;DR

  • pandas.DataFrame.applyのオプショナル引数に、result_type="expand"を指定する
  • pandas.DataFrame.applyの引数の関数(ラムダ式)は、タプルまたはリストを返すようにする
  • 代入式の左辺では、追加する列名をリストで指定する
def get_values(value0):
    # some calculation
    return value1, value2

df[["column1", "column2"]] = df.apply(
    lambda r: get_values(r["column0"]), 
    axis=1, 
    result_type="expand")

解説

適当なpandas.DataFrameがあるとします。

import pandas as pd

df = pd.DataFrame()
df["x"] = [1, 2, 3, 4, 5]
print(df)
   x
0  1
1  2
2  3
3  4
4  5

このxという名前の列を使って計算を行い、新たな列を作成したいとします。ベクトルのまま計算できる場合は簡単です。ここでは2乗を計算する場合を例に取ってみます。

df["x2"] = df["x"] ** 2
print(df)
   x  x2
0  1   1
1  2   4
2  3   9
3  4  16
4  5  25

もし新たな列の求める計算が複雑な関数で定義されており、ベクトルのまま計算できない場合には、pandas.DataFrame.applyを用いることができます。

def square(x):
    return x ** 2

df["x2"] = df.apply(lambda r: square(r["x"]), axis=1)
print(df)

もちろん結果は前と同じです。

さて、以下のような複数の値を返す関数を使って、複数列を同時に追加する場合はどうなるでしょうか?

def get_values(x):
    return x ** 2, x ** 3

次のように書くとエラーになります。

df[["x2","x3"]] = df.apply(lambda r: get_values(r["x"]), axis=1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-19-3039b5c1e701> in <module>
      1 def get_values(x):
      2     return x**2, x**3
----> 3 df[["x2", "x3"]] = df.apply(lambda r: get_values(r["x"]), axis=1)

(中略)

ValueError: Must have equal len keys and value when setting with an iterable

このエラーが起きている理由は、右辺の値をprintすることで分かります。

print(df.apply(lambda r: get_values(r["x"]), axis=1))
0       (1.0, 1.0)
1       (4.0, 8.0)
2      (9.0, 27.0)
3     (16.0, 64.0)
4    (25.0, 125.0)
dtype: object

2個の要素を持つタプルが入った(1列の)Seriesになってしまっています。
2列5行のDataFrameにするには、result_type="expand"を指定します。

df[["x2","x3"]] = df.apply(lambda r: get_values(r["x"]), axis=1, result_type="expand")
print(df)
   x    x2     x3
0  1   1.0    1.0
1  2   4.0    8.0
2  3   9.0   27.0
3  4  16.0   64.0
4  5  25.0  125.0

参考にしたリンク

3
12
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
3
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?