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

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

ただいまの
回答率

88.21%

pandasで月毎の合計を名前別に取得したい

解決済

回答 2

投稿 編集

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

hirohir03146

score 2

pandasでDataFrameから月ごとの合計を名前別に取得したいのですがうまくいきません。
どのように実装すればよろしいでしょうか。
以下のコードで名前毎に月別の合計値を取得できますが、月毎に名前別のデータを取得できません。

import pandas as pd
data = {'日付': ['2020/01/01','2020/01/01','2020/01/03','2020/01/03','2020/01/03','2020/02/06','2020/02/06','2020/02/08','2020/02/10','2020/02/10'],
        '名前': ['山田' , '田中' , '山田' , '田中' , '佐藤' , '山田' , '田中' , '山田' , '山田' , '佐藤' ],
        '金額': [1000,500,300,2000,1500,500,1000,3000,2000,4000]}
df = pd.DataFrame(data)
df['日付'] = pd.to_datetime(df['日付'],format='%Y/%m/%d')
df = df.set_index('日付')
df.groupby('名前').resample('M').sum()
金額
名前 日付
佐藤 2020-01-31 1500
2020-02-29     4000
山田 2020-01-31 1300
2020-02-29 5500
田中 2020-01-31 2500
2020-02-29 1000

今回上記とは別に以下のようなデータを取得したいと思っています。

金額
日付 名前
2020-01-31 佐藤 1500
山田 1300
田中 2500
2020-02-29 佐藤 1500
山田 5500
田中 1000
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+3

【方法1】

DataFrame.swaplevel()でマルチインデックスの順番を変更し、DataFrame.sort_index()で行を適切な順番に並び替えます。

import pandas as pd

# 質問文のコード
data = {'日付': ['2020/01/01','2020/01/01','2020/01/03','2020/01/03','2020/01/03','2020/02/06','2020/02/06','2020/02/08','2020/02/10','2020/02/10'],
        '名前': ['山田' , '田中' , '山田' , '田中' , '佐藤' , '山田' , '田中' , '山田' , '山田' , '佐藤' ],
        '金額': [1000,500,300,2000,1500,500,1000,3000,2000,4000]}
df = pd.DataFrame(data)
df['日付'] = pd.to_datetime(df['日付'],format='%Y/%m/%d')
df = df.set_index('日付')
df2 = df.groupby('名前').resample('M').sum()

# 処理ここから
df2.swaplevel().sort_index()
 日付         名前       金額 
 2020-01-31   佐藤       1500 
              山田       1300 
              田中       2500 
 2020-02-29   佐藤       4000 
              山田       5500 
              田中       1000 

追記:

【方法2】

pd.Grouper()を用いると、インデックスと通常の列の組み合わせでグルーピング処理を行うことができます。
pandas公式の解説

import pandas as pd

# 質問文のコード
data = {'日付': ['2020/01/01','2020/01/01','2020/01/03','2020/01/03','2020/01/03','2020/02/06','2020/02/06','2020/02/08','2020/02/10','2020/02/10'],
        '名前': ['山田' , '田中' , '山田' , '田中' , '佐藤' , '山田' , '田中' , '山田' , '山田' , '佐藤' ],
        '金額': [1000,500,300,2000,1500,500,1000,3000,2000,4000]}
df = pd.DataFrame(data)
df['日付'] = pd.to_datetime(df['日付'],format='%Y/%m/%d')
df = df.set_index('日付')

# 処理ここから
df.groupby([pd.Grouper(freq='M'), '名前']).sum()
 日付         名前       金額 
 2020-01-31   佐藤       1500 
              山田       1300 
              田中       2500 
 2020-02-29   佐藤       4000 
              山田       5500 
              田中       1000 

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2021/02/24 17:35

    ご回答ありがとうございます。
    方法2ですと最初から日付け毎、名前別に取得できるのでこちらで実装します!

    キャンセル

+2

冗長な気もしますが下記で一応出来たかと思います。

df2 = df.groupby('名前').resample('M').sum()
df2 = df2.reset_index().set_index('日付').groupby(['日付','名前']).sum()
print(df2)
#                    金額
#日付         名前    
#2020-01-31  佐藤    1500
#            山田    1300
#            田中    2500
#2020-02-29  佐藤    4000
#            山田    5500
#            田中    1000

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2021/02/24 10:07

    横から失礼しますが、
    最後は単に`df2 = df2.groupby(['日付','名前']).sum()`でも良いかと思います。

    キャンセル

  • 2021/02/24 10:29

    そうでしたね。アドバイスありがとうございます。ただコメントではなく回答として回答された方が良いかとおもいます。

    キャンセル

  • 2021/02/24 17:46

    reset_indexなしでも同じ結果になりました!
    ご回答ありがとうございます。

    キャンセル

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

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

関連した質問

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