2017-09-13 14 views
0

私はいくつかのデータフレームを持っています。以下はそれぞれの例です。 R1R2などのパンダのいくつかのデータフレームの計算

 df_min 
scale code R1 R2 ... 
    1  121 50 30 
    2  121 35 45 
    3  121 40 50 
    4  121 20 30 
    5  121 20 35 
    1  313 10 7 
    2  313 13 10 
    3  313 10 12 
    4  313 15 8 
    5  313 17 10 
... 

     df_rate 
scale code R1 R2 ... 
    1  121 20 40 
    2  121 30 20 
    3  121 20 30 
    4  121 15 40 
    5  121 10 30 
    1  313 10 5 
    2  313 15 10 
    3  313 25 10 
    4  313 10 15 
    5  313 20 5 
... 

     df_max 
scale code R1 R2 ... 
    1  121 30 200 
    2  121 100 175 
    3  121 70 100 
    4  121 80 90 
    5  121 75 35 
    1  313 60 70 
    2  313 35 70 
    3  313 50 60 
    4  313 50 45 
    5  313 45 68 
... 

    df_stock 
code R1 R2 ... 
121 100 150 
313 70 65 
.... 

     df_new 
scale code  R1 R2 ... 
    1  121 NaN NaN 
    2  121 NaN NaN 
    3  121 NaN NaN 
    4  121 NaN NaN 
    5  121 NaN NaN 
    1  313 NaN NaN 
    2  313 NaN NaN 
    3  313 NaN NaN 
    4  313 NaN NaN 
    5  313 NaN NaN 
... 

列が都市であり、多くはそこにすることができます。 code列には固有の製品コードがあります。彼らはまた多くのことができます。 scaleは、計算する週の番号を示します。それぞれcodeについては、5週間です。また、私は計算の結果を記録する必要がある空のデータフレームを持っています。

具体的な計算例を示しますが、より明確になることを願っています。空のデータフレームでは、scale1であり、code121であり、列がR1であるセルを取ります。私はdf_stockに対応する値を見つける。それは100に等しいです。それからdf_rateの値をR1の列から減算します。scale1です。この値はdf_minから少ない場合scale1で、私は、それを書き留め列R1、からの値よりも大きい場合、私はscale1ある列R1、からdf_maxから値を取ります。それは80と判明しました。それは50よりも大きいので、私はそれを書き留めます。次のセルについては、scale2である列R1の計算値(80)の次の値から減算します。そして私もそれをチェックする。それは50と判明しました。私はそれを書き留めます。等々。テーブルdf_stockから私は最初の値を取って、そこから減算を開始します。

実際には、df_minが最小値です。それを下回る場合は、対応する値をdf_maxからコピーする必要があります。

これらの計算は、各一意codeため(各code15からscale範囲に示されている)とR1R2等列ごとに行わなければなりません。次のように

例の結果は次のとおりです。

scale code R1 R2 ... 
    1  121 80 110 
    2  121 50 90 
    3  121 70 60 
    4  121 55 90 
    5  121 45 60 
    1  313 60 60 
    2  313 45 50 
    3  313 20 40 
    4  313 50 25 
    5  313 30 20 
... 

私は任意の助けのために非常に感謝されます!

UPD私が必要とするスクリプトを書きました。それは最適ではありませんが、私は他のアイデアはありません。それを変更してループを追加することは可能ですか?私の元のデータでは、scale126の間にあり、私のコードでは、scaleから各値の条件を書かなければなりません。

マイコード:

import pandas as pd 
import numpy as np 

a = (1,2,3,4,5,1,2,3,4,5,1,2,3,4,5) 
b = (121,121,121,121,121,313,313,313,313,313,444,444,444,444,444) 

columns = ['scale', 'code', 'R1', 'R2', 'R3'] 
index = np.arange(15) 

df_min = pd.DataFrame(columns=columns, index = index) 
df_min['scale'] = a 
df_min['code'] = b 
df_min['R1'] = np.random.randint(10, 50, size=15) 
df_min['R2'] = np.random.randint(10, 50, size=15) 
df_min['R3'] = np.random.randint(10, 50, size=15) 

df_rate = pd.DataFrame(columns=columns, index = index) 
df_rate['scale'] = a 
df_rate['code'] = b 
df_rate['R1'] = np.random.randint(5, 40, size=15) 
df_rate['R2'] = np.random.randint(5, 40, size=15) 
df_rate['R3'] = np.random.randint(5, 40, size=15) 

df_max = pd.DataFrame(columns=columns, index = index) 
df_max['scale'] = a 
df_max['code'] = b 
df_max['R1'] = np.random.randint(50, 150, size=15) 
df_max['R2'] = np.random.randint(50, 150, size=15) 
df_max['R3'] = np.random.randint(50, 150, size=15) 

index1 = np.arange(3) 
df_stock = pd.DataFrame(columns=columns, index = index1) 
df_stock['code'] = (121,313,444) 
df_stock['R1'] = np.random.randint(100, 300, size=3) 
df_stock['R2'] = np.random.randint(100, 300, size=3) 
df_stock['R3'] = np.random.randint(100, 300, size=3) 

df_new = pd.DataFrame(columns=columns, index = index) 
df_new['scale'] = a 
df_new['code'] = b 

# set the index to 'code' to subtract df_rate from df_stock 
df_stock = df_stock.set_index('code') 
df_rate = df_rate.set_index('code') 
df_new = df_stock - df_rate 
# have to add back in the 'scale' column since it wasn't present in df_rate 
df_new['scale'] = df_rate['scale'] 
# now set the index to use both 'code' and 'scale' 
df_new = df_new.reset_index() 
df_new = df_new.set_index(['code', 'scale']) 
df_min = df_min.set_index(['code', 'scale']) 
df_max = df_max.set_index(['code', 'scale']) 
df_new = df_new.mask(df_new < df_min, df_max) 

df_min = df_min.reset_index() 
df_min.insert(2, 'test', 0) 
df_max = df_max.reset_index() 
df_max.insert(2, 'test', 0) 
df_new = df_new.reset_index() 
df_new.insert(2, 'test', 0) 
df_rate = df_rate.reset_index() 
df_rate.insert(2, 'test', 0) 

df_new.loc[df_new['scale'].between(2,5), 'test':] = np.nan 

df_rate_p = df_rate.loc[df_rate['scale'] == 2, :'scale'] 
df_new.index +=1 
df_rate_p1 = df_new.loc[df_new['scale'] == 1, 'test':] - df_rate.loc[df_rate['scale'] == 2, 'test':] 
df_new2 = pd.concat([df_rate_p, df_rate_p1], axis=1) 
df_new = df_new.set_index(['code', 'scale']).fillna(df_new2.set_index(['code', 'scale'])).reset_index() 
df_new = df_new.mask(df_new < df_min, df_max) 

df_rate_p = df_rate.loc[df_rate['scale'] == 3, :'scale'] 
df_new.index +=1 
df_rate_p1 = df_new.loc[df_new['scale'] == 2, 'test':] - df_rate.loc[df_rate['scale'] == 3, 'test':] 
df_new2 = pd.concat([df_rate_p, df_rate_p1], axis=1) 
df_new = df_new.set_index(['code', 'scale']).fillna(df_new2.set_index(['code', 'scale'])).reset_index() 
df_new = df_new.mask(df_new < df_min, df_max) 

df_rate_p = df_rate.loc[df_rate['scale'] == 4, :'scale'] 
df_new.index +=1 
df_rate_p1 = df_new.loc[df_new['scale'] == 3, 'test':] - df_rate.loc[df_rate['scale'] == 4, 'test':] 
df_new2 = pd.concat([df_rate_p, df_rate_p1], axis=1) 
df_new = df_new.set_index(['code', 'scale']).fillna(df_new2.set_index(['code', 'scale'])).reset_index() 
df_new = df_new.mask(df_new < df_min, df_max) 

df_rate_p = df_rate.loc[df_rate['scale'] == 5, :'scale'] 
df_new.index +=1 
df_rate_p1 = df_new.loc[df_new['scale'] == 4, 'test':] - df_rate.loc[df_rate['scale'] == 5, 'test':] 
df_new2 = pd.concat([df_rate_p, df_rate_p1], axis=1) 
df_new = df_new.set_index(['code', 'scale']).fillna(df_new2.set_index(['code', 'scale'])).reset_index() 
df_new = df_new.mask(df_new < df_min, df_max) 
df_new 

答えて

1

使ってパンダindexMultiIndexはお互いに正しい行を比較するために非常に有用です。ここで

は、あなたがそれを使用する方法である:答えのための

# set the index to 'code' to subtract df_rate from df_stock 
df_stock = df_stock.set_index('code') 
df_rate = df_rate.set_index('code') 
df_new = df_stock - df_rate 
# have to add back in the 'scale' column since it wasn't present in df_rate 
df_new['scale'] = df_rate['scale'] 

# now set the index to use both 'code' and 'scale' 
df_new = df_new.reset_index() 
df_new = df_new.set_index(['code', 'scale']) 
df_min = df_min.set_index(['code', 'scale']) 
df_max = df_max.set_index(['code', 'scale']) 

# you may not actually need these lines, but sometimes it is necessary! 
# intersection = df_new.index.intersection(df_min.index).intersection(df_max.index) 
# df_new = df_new.loc[intersection] 
# df_min = df_min.loc[intersection] 
# df_max = df_max.loc[intersection] 

# if df_new < df_max, then use values from df_max 
# I didn't actually understand what you meant to do with the 
# the data, so this is probably not quite what you intended, 
# but you can can use this to see how it works and implement 
# your algorithm 
df_new = df_new.mask(df_new < df_min, df_max) 
+0

ありがとう!それは本当に私が仕事に移るのを助けました。 –

関連する問題