複数の引数を持つ関数を適用して新しいパンダ列を作成する


165

pandas既存の2つの列に関数を適用して、データフレームに新しい列を作成します。この回答に従って、引数として1つの列のみが必要な場合に新しい列を作成することができました。

import pandas as pd
df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})

def fx(x):
    return x * x

print(df)
df['newcolumn'] = df.A.apply(fx)
print(df)

ただし、関数に複数の引数が必要な場合に同じことを行う方法はわかりません。たとえば、列Aと列Bを以下の関数に渡して新しい列を作成するにはどうすればよいですか?

def fxy(x, y):
    return x * y

回答:


136

または、numpyの基礎となる関数を使用できます。

>>> import numpy as np
>>> df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})
>>> df['new_column'] = np.multiply(df['A'], df['B'])
>>> df
    A   B  new_column
0  10  20         200
1  20  30         600
2  30  10         300

または、一般的な場合には任意の関数をベクトル化します。

>>> def fx(x, y):
...     return x*y
...
>>> df['new_column'] = np.vectorize(fx)(df['A'], df['B'])
>>> df
    A   B  new_column
0  10  20         200
1  20  30         600
2  30  10         300

2
答えてくれてありがとう!知りたいのですが、これが最速の解決策ですか?
MV23

6
を使用したベクトル化バージョンnp.vectorize()は驚くほど高速です。ありがとうございました。
stackoverflowuser2010

これは便利なソリューションです。関数xとyへの入力引数のサイズが等しくない場合、エラーが発生します。その場合、@ RomanPekarソリューションは問題なく機能します。性能比較はしていません。
Ehsan Sadr

私はこれが古い答えであることを知っていますが、私はエッジケースがあり、np.vectorize機能しません。その理由の1つは、列の1つがタイプpandas._libs.tslibs.timestamps.Timestampでありnumpy.datetime64、ベクトル化によってタイプに変換されるためです。2つのタイプは互換性がないため、関数の動作が低下します。これについて何か提案はありますか?(.applyこれは明らかに避けられるべきもの以外)
ElRudi

素晴らしい解決策!ベクトル化がうまく機能し、文字列比較関数でも非常に高速だと誰かが思っている場合に備えて。
infiniteloop

227

関数を書き換えることが可能な場合は、@ greenAfricanの例を使用できます。ただし、関数を書き直したくない場合は、次のように、apply内で匿名関数にラップできます。

>>> def fxy(x, y):
...     return x * y

>>> df['newcolumn'] = df.apply(lambda x: fxy(x['A'], x['B']), axis=1)
>>> df
    A   B  newcolumn
0  10  20        200
1  20  30        600
2  30  10        300

4
これはすばらしいヒントであり、列の参照は(実際には)apply呼び出しの近くに残ります。このヒントと、提供されている複数列の出力ヒント@toto_ticoを使用して、3列入力、4列出力の関数を生成しました!よく働く!
RufusVS 2018

7
うわー、OPの最小限の例に焦点を当てていないのはあなただけですが、問題全体に対処しています。:)
Matt

38

これは問題を解決します:

df['newcolumn'] = df.A * df.B

あなたも行うことができます:

def fab(row):
  return row['A'] * row['B']

df['newcolumn'] = df.apply(fab, axis=1)

10
この回答はこのおもちゃの例を解決し、実際の関数を書き換えるには十分ですが、以前に定義した関数を参照列に書き換えずに適用する方法については触れていません。
マイケル

23

一度に複数の列作成する必要がある場合:

  1. データフレームを作成します。

    import pandas as pd
    df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})
  2. 関数を作成します。

    def fab(row):                                                  
        return row['A'] * row['B'], row['A'] + row['B']
  3. 新しい列を割り当てます。

    df['newcolumn'], df['newcolumn2'] = zip(*df.apply(fab, axis=1))

1
1つの適用で複数の列を生成するにはどうすればよいかと思っていました。@Roman Pekarの回答でこれを使用して、3列イン、4列アウトの関数を生成しました!よく働く!
RufusVS 2018

15

もう1つのdictスタイルのクリーンな構文:

df["new_column"] = df.apply(lambda x: x["A"] * x["B"], axis = 1)

または、

df["new_column"] = df["A"] * df["B"]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.