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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

2回答

1507閲覧

Pandas 累積中央値 cumulative medianの出し方

smbdofgcccpl

総合スコア16

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2020/12/22 08:35

編集2020/12/22 09:32

やりたいこと

pandasのデータフレームで以下のようなデータフレーム(df)があります。

iddatesales
A12020/01/012000.0
A12020/01/151000.0
A12020/02/103000.0
A22020/01/011000.0
A22020/01/102000.0
A22020/01/203000.0
A22020/02/20NaN
A22020/03/011000.0

id、monthでグループ化し、salesの累積中央値を算出したいです。
(以下のイメージ)

idmonthmedian_sales
A1Jan1500.0
A1Feb2000.0
A2Jan2000.0
A2Feb2000.0
A2Mar1500.0

A1のFebのmedian salesは、A1の1月、2月のsalesの中での中央値を取得したいです。
A2のFebのmedian salesは、A2の1月、2月のsalesの中での中央値を取得したいです。
A2のMarのmedian salesは、A2の1月、2月、3月のsalesの中での中央値を取得したいです。

試したこと

以下のプログラムを考えましたが、期待した結果にはなりませんでした。

python

1df['month'] = pd.DatetimeIndex(df['date']).month 2df['median_sales'] = df.groupby(['id', 'month'])['sales'].expanding().median().reset_index()

cumsum, cumcountみたいな関数が見つからず、実装方法が思いつきません。
皆様、お忙しいとは思いますが、何卒宜しくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

これで、smbdofgcccplさんの求めるものとあっていますか?
ただし、saleは0ではないこと仮定しています。

python

1>>> import pandas as pd 2>>> import numpy as np 3>>> 4>>> df = pd.DataFrame([['A1', '2020/01/01', 2000.0], 5... ['A1', '2020/01/15', 1000.0], 6... ['A1', '2020/02/10', 3000.0], 7... ['A2', '2020/01/01', 1000.0], 8... ['A2', '2020/01/10', 2000.0], 9... ['A2', '2020/01/20', 3000.0], 10... ['A2', '2020/02/20', np.NaN], 11... ['A2', '2020/03/01', 1000.0]], 12... columns = ['id', 'date', 'sales']) 13>>> 14>>> df['date'] = pd.to_datetime(df['date']) 15>>> df['month'] = df['date'].dt.month 16>>> 17>>> df2 = pd.DataFrame(np.diag(df.sales.values)) 18>>> df3 = pd.concat([df.drop('sales',axis=1), df2], axis=1) 19>>> df4 = df3.groupby(['id', 'month']).sum() 20>>> df5 = df4.where(df4 != 0.0) 21>>> df6 = df5.median(axis=1) 22>>> df7 = df6[pd.isnull(df6)==False] 23>>> print(df7) 24id month 25A1 1 1500.0 26 2 3000.0 27A2 1 2000.0 28 3 1000.0 29dtype: float64

現時点の入力から計算した結果はsmbdofgcccplさんの書いている結果とは異なっていますが、これは、smbdofgcccplさんの修正漏れのように思います。
複数年にまたがる場合は、月だけではなく年も入れたほうが良いと思いますが、簡単ですので、必要に応じてご自分で修正してください。

投稿2020/12/22 13:58

編集2020/12/22 14:54
ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ちょっと自信ないですが累積対象=グループ化した値以下を持つと考えてよいと思われます。
であれば以下のようなコードで累積した対象を抽出して結果を得ることができます。

Python

1import pandas as pd 2from io import StringIO 3 4# テストデータ 5s = """id,date,sales 6A1,2020/01/01,1000 7A1,2020/01/15,2000 8A1,2020/02/10,3000 9A2,2020/01/01,1000 10A2,2020/01/10,2000 11A2,2020/01/20,3000""" 12df = pd.read_csv(StringIO(s)) 13df['date'] = pd.to_datetime(df['date']) 14df['month'] = pd.DatetimeIndex(df['date']).month 15 16grp = df.groupby(['id','month']) 17df2 = grp.mean().reset_index() 18 19# 累積対象=グループ化した値以下を持つ 20med = [] 21for t in grp.groups.keys(): 22 med.append( df[ (df['id'] <= t[0]) & (df['month'] <= t[1])]['sales'].median()) 23 24df2['sales_med'] = med 25print(df2) 26# id month sales sales_med 27#0 A1 1 1500 1500.0 28#1 A1 2 3000 2000.0 29#2 A2 1 2000 2000.0

投稿2020/12/22 09:12

can110

総合スコア38341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問