質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

88.63%

Python pandas:列同士の計算方法について

解決済

回答 2

投稿

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

omixin

score 50

Pythonでpandasによるデータ分析処理を進めていて、列同士の演算の仕方について教えてもらえないでしょうか。

import datetime
import pandas as pd

df1 = pd.DataFrame({'date': ["2019-03-04", "2019-03-07", "2019-03-14"], 
                    'diff_days': [4, 7, 11]})

print(df1)

# """結果"""
#            date  diff_days
# 0    2019-03-04          4
# 1    2019-03-07          7
# 2    2019-03-14         11

例えばこのようなデータフレームがあったときに、新たに1列追加して、
date列にdiff_daysの値分の日数を後ろにずらした日を取得したいとします。

リスト内方表記を使えば下記のように書けるのですが、できればmap()などでスマートかつリスト内方表記を避けて書けるように
なりたいため、そういった方法を教えてもらいたいと思います。

## リスト内方表記ではzip()を使ってこのようにかけるが、コードが読みづらくなる懸念がある
df1['after_date'] = [datetime.datetime.strptime(x, '%Y-%m-%d') + datetime.timedelta(y) for x, y in zip(df1['date'], df1['diff_days'])]
df1

# """結果"""
#             date  diff_days  after_date
# 0     2019-03-04          4  2019-03-08
# 1     2019-03-07          7  2019-03-14
# 2     2019-03-14         11  2019-03-25

ちなみに、今回は複数列の計算なので若干複雑になっているのですが、単列を使った計算であれば下記のようにリスト内方表記を避けて書けます。参考までに記載します。

## date列の値を使って、一律で1日後ろにずらす
df1['1day_after_date'] = df1['date'].map(lambda x: datetime.datetime.strptime(x, '%Y-%m-%d') + datetime.timedelta(1))
df1

# """結果"""
#            date  diff_days  1day_after_date
# 0    2019-03-04          4       2019-03-05
# 1    2019-03-07          7       2019-03-08
# 2    2019-03-14         11       2019-03-15

よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

こんな感じでapplyを使って書けば良いです。

import pandas as pd
import datetime

df1 = pd.DataFrame({'date': ["2019-03-04", "2019-03-07", "2019-03-14"], 
                    'diff_days': [4, 7, 11]})
df1["date"] = pd.to_datetime(df1["date"])  # 予め日付時刻型にしておかないと扱いづらいので

def f(row):
    return row["date"] +  datetime.timedelta(days=row["diff_days"])

result = df1.apply(f, axis=1)
print(result)  # 必要に応じて適宜列に追加してください

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/09/09 16:38

    apply()について初見でした!
    勉強になります。ありがとうございます。

    キャンセル

+1

そもそも型が適切であれば、apply()も不要ではないかと思います。

import pandas as pd

df1 = pd.DataFrame({'date': ['2019-3-4','2019-3-7','2019-3-14'],
                    'diff_days': [4,7,11]})
# date列は datetime型、 diff_days列は timedelta型
df1['date'] = pd.to_datetime(df1['date'])
df1['diff_days'] = pd.to_timedelta(df1['diff_days'], unit='d')

df1['affter_date'] = df1['date'] + df1['diff_days']
#        date diff_days affter_date
#0 2019-03-04    4 days  2019-03-08
#1 2019-03-07    7 days  2019-03-14
#2 2019-03-14   11 days  2019-03-25

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/09/09 18:31

    回答ありがとうございます。
    質問の意図として、今回の計算だけではなく、今後複雑な処理にも耐えられるような方法論が知りたかったため、関数を適用させていける方法としてapplyの方をベストアンサーとさせていただきます。

    確かに今回のケースに限っては、型が適切であれば単純な足し算で解決できますね。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る