2016-10-23 9 views
0

私は1日のレベルで1列の値を持ち、1週間のレベルでは別の列の値を持っています。私は、1日の値を、その日が属する週の週の値で除算し、対応する会社とグループに分けたいと考えています。私はループなしでやり遂げる方法を見つけ出そうとしているし、パンダやナンディでこれを行う方法があるように感じるが、私はそれを理解することはできない。助けてくれてありがとう!パンダのデータフレームは日付に基づいて行を分割します

たとえば、私は2つのデータフレームがあります。

DF1 =

Company Group Date  People 
A  X  01/07/2015 5 
A  X  01/14/2015 10 
A  XX 01/07/2015 6 
A  XX 01/14/2015 12 
B  Y  01/07/2015 4 
B  Y  01/14/2015 8 
B  YY 01/07/2015 5 
B  YY 01/14/2015 4 

DF2 =

Company Group Date  Value 
A  X  01/04/2015 5 
A  X  01/06/2015 10 
A  X  01/13/2015 15 
A  XX 01/05/2015 6 
A  XX 01/06/2015 9 
A  XX 01/11/2015 9 
A  XX 01/14/2015 12 
B  Y  01/05/2015 4 
B  Y  01/07/2015 6 
B  Y  01/13/2015 16 
B  Y  01/14/2015 24 
B  YY 01/03/2015 10 
B  YY 01/11/2015 10 
B  YY 01/14/2015 12 

をそして、私は結果がなりたい:

Company Group Date  Value/People 
A  X  01/04/2015 1 
A  X  01/06/2015 2 
A  X  01/13/2015 1.5 
A  XX 01/05/2015 1 
A  XX 01/06/2015 1.5 
A  XX 01/11/2015 0.75 
A  XX 01/14/2015 1 
B  Y  01/05/2015 1 
B  Y  01/07/2015 1.5 
B  Y  01/13/2015 2 
B  Y  01/14/2015 3 
B  YY 01/03/2015 2 
B  YY 01/11/2015 2.5 
B  YY 01/14/2015 3 
+0

あなたの日付は一意ではありませんので、あなたは一日が属する週の値によって分割したいとき...どの値あなたは選ぶのですか?このデータでは不十分です。試したループを見せてください。 – piRSquared

+0

対応する会社およびグループに基づいて値を選択したいと考えています。たとえば、df2(会社AとグループX)の最初の行については、会社A、グループXに対応するdf1の行で値を除算するとします。ここでdf2(01/04/2015)の日付が下がりますdf1(01/07/2015)の週に私はこれをもっと明確にするために私の質問を修正しました。 – user3357979

答えて

1

日付のような基になるdtype DataFramesとSeriesに格納されている値はNumPy datetime64[ns]です。 datetime64[ns]値の配列は、標準的な第二に、「トリミング」することができ、分、時間、日、週、月、または年(適切な単位に置き換えられ?astype('datetime64[?]')を呼び出すことによって、例えばsmhDWM,Y)。

ここで、各日付を正式な週に分類すると、私たちの問題は大きく解決されます。私たちは、.astype('datetime64[W]')を使用してこの操作を行うことができます。

In [152]: df1['Week'] = df1['Date'].values.astype('datetime64[W]'); df1 
Out[152]: 
    Company  Date Group People  Week 
0  A 2015-01-07  X  5 2015-01-01 
1  A 2015-01-14  X  10 2015-01-08 
2  A 2015-01-07 XX  6 2015-01-01 
3  A 2015-01-14 XX  12 2015-01-08 
4  B 2015-01-07  Y  4 2015-01-01 
5  B 2015-01-14  Y  8 2015-01-08 
6  B 2015-01-07 YY  5 2015-01-01 
7  B 2015-01-14 YY  4 2015-01-08 

df1df2の両方のためにこれをやった、我々は今、['Week', 'Group', 'Company']上のデータフレームをマージすることができます。これは、df1とdf2の適切な行と一致します。 Value to Peopleの比率を見つけることは簡単です。


import pandas as pd 
df1 = pd.DataFrame({'Company': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'], 'Date': ['01/07/2015', '01/14/2015', '01/07/2015', '01/14/2015', '01/07/2015', '01/14/2015', '01/07/2015', '01/14/2015'], 'Group': ['X', 'X', 'XX', 'XX', 'Y', 'Y', 'YY', 'YY'], 'People': [5, 10, 6, 12, 4, 8, 5, 4]}) 

df2 = pd.DataFrame({'Company': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B'], 'Date': ['01/04/2015', '01/06/2015', '01/13/2015', '01/05/2015', '01/06/2015', '01/11/2015', '01/14/2015', '01/05/2015', '01/07/2015', '01/13/2015', '01/14/2015', '01/03/2015', '01/11/2015', '01/14/2015'], 'Group': ['X', 'X', 'X', 'XX', 'XX', 'XX', 'XX', 'Y', 'Y', 'Y', 'Y', 'YY', 'YY', 'YY'], 'Value': [5, 10, 15, 6, 9, 9, 12, 4, 6, 16, 24, 10, 10, 12]}) 

for df in [df1, df2]: 
    df['Date'] = pd.to_datetime(df['Date']) 
    df['Week'] = df['Date'].values.astype('datetime64[W]') 

result = pd.merge(df2, df1, how='left', on=['Week', 'Group', 'Company'], suffixes=['', '_1']) 
result['Value/People'] = result['Value']/result['People'] 
result = result[['Company', 'Group', 'Date', 'Value/People']] 
print(result) 

利回り

正規の週に日付をトリミングする際に考慮される必要があり、 "ベースオフセット" の問題があることを
Company Group  Date Value/People 
0  A  X 2015-01-04   1.00 
1  A  X 2015-01-06   2.00 
2  A  X 2015-01-13   1.50 
3  A XX 2015-01-05   1.00 
4  A XX 2015-01-06   1.50 
5  A XX 2015-01-11   0.75 
6  A XX 2015-01-14   1.00 
7  B  Y 2015-01-05   1.00 
8  B  Y 2015-01-07   1.50 
9  B  Y 2015-01-13   2.00 
10  B  Y 2015-01-14   3.00 
11  B YY 2015-01-03   2.00 
12  B YY 2015-01-11   2.50 
13  B YY 2015-01-14   3.00 

注意。言い換えれば、いつ週が始まるかを決める必要があります。標準的な選択がdf['Date'].values.astype('datetime64[W]')であるのが気に入らない場合は、日付にオフセットを追加する必要があります。たとえば、あなたが使用することができdf['Date']の日付に日を追加します

(df['Date'].values + np.timedelta64(1, 'D')).astype('datetime64[W]') 
関連する問題