pandas apply 複数列 複数行の値を引数で

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 59

marymills

score 11

前提・実現したいこと

複数列 複数行の値を引数に関数に与えて帰ってきた値を新しい列で追加したい

4つの引数を与える関数があります
def my_func(x1, y1, x2, y2):

長いので処理省略
   
return R

pandasの
x1= A列の1行め
x2=B列の1行め
y1=A列の2行め
y2=B列の2行め
を引数でmy_funcの帰ってきた値を
R列1行めに追加したい

x1= A列の2行め 
x2=B列の2行め
y1=A列の3行め
y2=B列の3行め
を引数でmy_funcの帰ってきた値を
R列2行めに追加したい
:::::

と最後の行までR列に値を入れたい

見つけて試そうと思ったコード

def func(row):
return row['A'] + row['B'] + row['C']

import pandas as pd
df = pd.DataFrame({'A':[1,2,3],'B':[10,20,30],'C':[100,200,300]})
df['D'] = df.apply( func, axis=1)
print (df)

⬆︎2行分の書き方がよくわかりませんでした

②  

import pandas as pd
df = pd.DataFrame({ 'A' : [1, 2, 3, 4, 5], 'B' : [10, 20, 30, 40, 50] })

df['D'] = list(map(lambda x, y: x + y, df['A'], df['B'].shift(-1)))
print(df)

A   B     D
0  1  10  21.0
1  2  20  32.0  
2  3  30  43.0
3  4  40  54.0
4  5  50   NaN

⬆︎ 
df['A'] + df['B'].shift(-1) 
1+20
2+30
3+40
4+50

df['D'] = list(map(lambda x, y: x + y, df['A'], df['B'].shift(-1)))
を変えればいいのかなまでは理解できましたが
そのさきが思うようにできませんというよりどう書いていいかわからずといったところがです

発生している問題・エラーメッセージ

TypeError: ("'Series' object is not callable", 'occurred at index A')

該当のソースコード

試したこと

df["R"] = df.apply(func1(df['A'],df['B'], df['A'].shift(-1), df['B'].shift(-1)))

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • t_obara

    2019/09/11 16:40

    入力に対し、期待する出力を提示した方がよろしいかと。
    あと、コードは```で囲ってください。

    キャンセル

  • magichan

    2019/09/11 16:45

    いまひとつ仕様が明確ではありません。
    2行目以降はどのように処理をするのでしょうか?
    1行目をX に2行目をyに割り振る
    2行目をX に3行目をyに割り振る
    3行目をX に4行目をyに割り振る
    ・・・
    と繰り返すのですか?
    それとも単純に
    奇数行はX、偶数行はyに割り振る
    ということでしょうか?
    また後者の場合戻ってきた値を、奇数行と偶数行に同じ値を書き込むのですか?それとも奇数行にのみかきこむのですか?

    キャンセル

  • meg_

    2019/09/11 20:35

    forループでの処理では駄目なのですか?

    キャンセル

回答 1

checkベストアンサー

0

質問の編集ありがとうございました。

今回の仕様の場合

  • 『複数行にapply()を適用する』

と考えるよりも

  • 『複数行をまとめたDataFrameを作成し、そろDataFrameに対してapply()を適用する』

と考える方がシンプルです。

データのまとめ方ですが、まず各行の1つ下の行はに書かれているように DataFrame.shift(-1) にて得ることができますので、
前処理として、'A'列と'B'列をshift(-1)した行をそれぞれ 'A2'列と'B2'列に名前を変更(rename())を行い、元のDataFrameに結合(join())します。
すると

import pandas as pd

df = pd.DataFrame({ 'A' : [1, 2, 3, 4, 5], 'B' : [10, 20, 30, 40, 50] })
df = df.join(df[['A', 'B']].rename(columns={'A':'A2','B':'B2'}).shift(-1))
#   A   B   A2    B2
#0  1  10  2.0  20.0
#1  2  20  3.0  30.0
#2  3  30  4.0  40.0
#3  4  40  5.0  50.0
#4  5  50  NaN   NaN

となりますので、このDataFrameの各行に対して apply() を適用すると良いだけとなります。
DataFrameの各列を関数 my_func(x1, y1, x2, y2)の各パラメータに対応させるには、lambda を経由して

df['R'] = df.apply(lambda row:f(row['A'],row['A2'],row['B'],row['B2']), axis=1)


または

df['R'] = df.apply(lambda row:f(*row[['A','A2','B','B2']]), axis=1)


の様に呼ぶことでの行えるかと思います。

あとは、もし'A2'列と'B2'列が不要であれば、以下のように削除するだけです。

df = df.drop(columns=['A2', 'B2'])

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/12 14:57

    行を増やすという発想が全くなかったのでありがとうございました。
    出来ました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる