2016-05-01 10 views
3

私は日付、卸売業者、製品、販売の4つの列を持つcsvファイルを持っています。私は、各製品と卸売業者の組み合わせごとに、過去52週間の売上の平均を各日付ごとに求めています。これは、過去52週間の時間「C」における卸売業者「B」における製品「A」の前回の平均販売額を意味する。Pythonで毎回過去52週間の売上げの平均を見つけるには

たとえば、1月、4月、5月、8月の卸売業者Bでの製品「A」の販売数がそれぞれ100,200,300,400であることがわかっています。 Janの前にはレコードがないと仮定してください。したがって、4月の卸売業者Bの前回の製品Aの平均販売価格は100/1、5月は(200 + 100)/ 2、 8月の(300 + 200 + 100)/ 3です。

date wholesaler product sales 
12/31/2012 53929 UPE54  4 
12/31/2012 13131 UPE55  1 
2/23/2013 13131 UPE55 1156 
4/24/2013 13131 UPE55  1 
12/1/2013 83389 UPE54  9 
12/17/2013 83389 UPE54  1 
12/18/2013 52237 UPE54  9 
12/19/2013 53929 UME24  1 
12/31/2013 82204 UPE55  9 
12/31/2013 11209 UME24  4 
12/31/2013 52237 UPE54  1 

今、私が使用しています:各製品-問屋の組み合わせのため、以前の売上高の合計平均(最後のない52週間)を与える

df = pd.read_csv('Sample.csv',index_col='date') 

expd_gb = df.reset_index().groupby(['wholesaler', 'product'])['sales'].apply(pd.Series.expanding) 
idx = df.reset_index().groupby(['wholesaler', 'product', 'date'])['sales'].count().index 

cnct = pd.concat([expd_gb.iloc[n].mean().shift(1) for n in range(len(expd_gb))]) 
cnct.index = idx 

次の表は、私のデータを示しています。結果は次のとおりです。

wholesaler product date  
11209  UME24 12/31/2013  NaN 
13131  UPE55 12/31/2012  NaN 
        2/23/2013  1.0 
        4/24/2013  578.5 
52237  UPE54 12/18/2013  NaN 
        12/31/2013  9.0 
53929  UME24 12/19/2013  NaN 
      UPE54 12/31/2012  NaN 
82204  UPE55 12/31/2013  NaN 
83389  UPE54 12/1/2013  NaN 
        12/17/2013  9.0 

時間が経過するにつれて、売上レコードの反復が増えています。私は最後の52週間の売上の平均が何かを調べる必要があります。これは、特定の日付(例えば、2015年11月6日)を意味します。これは、過去52週間の特定の卸売業者での製品の平均販売額を意味します。あなたの助けに100万こんにちは!

答えて

2

applyは、レコードごとに卸売業者と製品による最後の52週間の売上を条件付きで平均化する機能を考慮してください。回避策がなければ、groupby()はグループの同じ値を返しますが、グループの平均実行タイプが必要なので、シリーズで処理してみてください。また、timedelta()を使用して52週間をカウントできるように、日付をdatetime形式に変換してください。

import pandas as pd 
import datetime 

dateparse = lambda x: pd.datetime.strptime(x, '%m/%d/%Y') 

df = pd.read_csv('Sample.csv', index_col='date', 
       parse_dates=[0], date_parser=dateparse) 

def last52weeks(x): 
    ser = df['sales'][(df.index >= x.name - datetime.timedelta(weeks=52)) & 
         (df.index <= x.name) & 
         (df['wholesaler'] == x[0]) & 
         (df['product'] == x[1])] 
    return ser.mean() 

df['avg_sales_last52weeks'] = df.apply(last52weeks, axis=1) 
df = df.sort_values(['wholesaler', 'product']) 

#    wholesaler product sales avg_sales_last52weeks 
# date               
# 2013-12-31  11209 UME24  4      4.0 
# 2012-12-31  13131 UPE55  1      1.0 
# 2013-02-23  13131 UPE55 1156     578.5 
# 2013-04-24  13131 UPE55  1     386.0 
# 2013-12-18  52237 UPE54  9      9.0 
# 2013-12-31  52237 UPE54  1      5.0 
# 2013-12-19  53929 UME24  1      1.0 
# 2012-12-31  53929 UPE54  4      4.0 
# 2013-12-31  82204 UPE55  9      9.0 
# 2013-12-01  83389 UPE54  9      9.0 
# 2013-12-17  83389 UPE54  1      5.0 
+0

ありがとうございます!それは素晴らしいです!'timedelta()'関数がより速く動作すると思いますか?実際には2500万行以上を計算する必要があり、結果を見つけるための最速の方法を見つけたいと考えています。もう一度あなたの優雅なコードをありがとう! – Ashkan

+1

うわー!かなりのデータセット。日付の平均および索引表を実行するための条件付き集約照会を使用するデータベースSQLソリューションを考えてみましょう。次にパンダに輸入する。 – Parfait

+0

コメントありがとうございました!それは良いアイデアです。 – Ashkan

1

平均が週平均である場合、cnct = pd.concat([expd_gb。])で平均を取得するのではなく、週数(つまり、卸売業者1台あたり)で52を分けるべきではありません。範囲内のn(len(expd_gb))])に対してiloc [n] .mean()。shift(1)?

52週間未満の場合は、その卸売業者のその製品の合計売上をあなたが所持している週数で割ります。たとえば、1月に(2016年)1月に100個のウィジェットを販売した場合、2月に200、3月に400を販売した場合、4月1日現在の合計売上は700になります。1月31日、2月29日、3月31日です。総日数は91日で、13週(91/7)になります。その3ヶ月間の週平均売り上げは、したがって、700/13または約1日になります。週53.85ウィジェット。あなたが91の日誌記録、13の週記録、または3つの月記録を持っていても、毎週の平均はまだ同じです。

timedeltaオブジェクトを調べるには、日数(およびその週数)を取得する必要があります。 52週間を過ぎると、timedeltaを使用して、52週間(または364日)前の日付と、その日付より前に何かを破棄したファイルを読み取った日付を調べることができます。

+0

ご意見ありがとうございました!それはちょっと解きました。最初の1年では、卸売業者1台につき52個のレコードしか得られなかったので、すべてのレコードの平均を使用することができますが、来年は平均52週間の平均を探します。また、すべての製品と卸売業者との組み合わせには、特定の製品の卸売業者にとって意味する毎週の記録がないため、平均は合計(12レコード)/ 52である必要があります。実際にあなたのコメントは真実だと思いますが、ロジックを妨げる方法はわかりません! – Ashkan

関連する問題