2017-02-07 42 views
3
DF的

例子集1個條件新列:基於使用索引和一列GROUPBY

   Category Weight Test 
1/21/2017  SuperMarket 0.02 Nan 
1/21/2017  SuperMarket 0.18 Nan 
1/21/2017  SuperMarket 0.71 Nan 
1/21/2017  Hotel  0.53 Nan 
1/21/2017  Hotel  0.93 0.93 
1/21/2017  Hotel  0.97 Nan 
1/21/2017  Bar   0.13 Nan 
1/21/2017  Bar   0.31 Nan 
1/21/2017  Bar   0.96 Nan 
1/21/2017  Bar   0.65 0.65 
1/21/2017  Bar   0.27 0.27 
1/21/2017  Bar   0.24 Nan 
1/21/2017  Hospital 0.65 0.65 
1/21/2017  Hospital 0.90 0.90 
1/21/2017  Hospital 1.00 1.00 

新柱df['Adjusted_weight']這將基於3個條件被分配的值:

  1. 如果出於任何日期並且類別df['Test']僅包含Nans,則df['Adjusted_weight'] = df['weight']
  2. 如果對於任何日期和類別df['Test']僅包含值(無Nans),則df['Adjusted_weight'] = df['weight']
  3. 最後,如果對於任何日期和類別,如果df['Test']包含這兩個值和NaN,則:

ⅰ)對於其中df['Test'] = Nan,然後df['Adjusted_weight'] = df['weight'] * 0.5

ⅱ)對於其中df['Test'] = value,然後df['Adjusted_weight'] = df['weight'] + SUM (df['weight'] - df['adjusted_weight'])/ number of non Nan values數非南非有*爲NaNs。

在部分ii)中,我們將調整後的權重按比例放大,以使調整後的權重(在第3部分中)的總和等於權重的總和(對於特定日期和類別)。

輸出示例:

   Category Weight Test Adjusted Weight 
1/21/2017  SuperMarket 0.02 Nan  0.02 
1/21/2017  SuperMarket 0.18 Nan  0.18 
1/21/2017  SuperMarket 0.71 Nan  0.71 
1/21/2017  Hotel  0.53 Nan  0.265 
1/21/2017  Hotel  0.93 0.93  1.68 
1/21/2017  Hotel  0.97 Nan  0.485 
1/21/2017  Bar   0.13 Nan  0.07 
1/21/2017  Bar   0.31 Nan  0.16 
1/21/2017  Bar   0.96 Nan  0.48 
1/21/2017  Bar   0.65 0.65  1.06 
1/21/2017  Bar   0.27 0.27  0.68 
1/21/2017  Bar   0.24 Nan  0.12 
1/21/2017  Hospital 0.65 0.65  0.65 
1/21/2017  Hospital 0.90 0.90  0.90 
1/21/2017  Hospital 1.00 1.00  1.00 

的我怎樣填充酒店2007年1月21日一個例子。哪裏有2個南和1個值。所以對於南非來說,調整後的重量只有df['weight'] * 0.5

現在爲哪裏有一個值,它只是0.93 + (0.53 - 0.265) + (0.97 - 0.485)其中= 1.68

剛添加SECTION

對於酒吧的例子中,有4個楠值其中df['Adjusted weight'] = 0.5* df['weight']。現在,2017年1月21日的酒吧有兩個值。他們都需要將權重添加到df ['adjusted_weight'],以便總和等於2017年1月21日酒吧的df ['weight']。因此,計算結果爲(0.13-0.07)+(0.31-0.16)+(0.96-0.48)+(0.24-0.12)= 0.82,因爲有兩個值要分配,0.41會加到0.65和0.27之間,等於1.06和0.68。

我們可能有任意數量的Nans和值,或者只有Nans和只有值。

其基本目標是在具有值的日期和類別內放大並確保該框(日期,類別)中的權重與以前相同。

我有很多日期,數據比顯示的大得多。謝謝。

回答

1

您可以定義一個函數,在分組完成後將其傳遞給apply以執行所有計算。

def f(x): 
    count = x.Test.count() 
    size = x.Test.size 
    if count == 0 or count == size: 
     return x.Weight 
    else: 
     adj_null = x.Weight * x.Test.isnull() * .5 
     notnull = x.Test.notnull() 
     distribute = adj_null.sum()/notnull.sum() 
     adj_notnull = (x.Weight + distribute) * notnull 
     return adj_null + adj_notnull 

df['Adjusted Weight'] = df.groupby([pd.TimeGrouper('D'), 'Category'], sort=False).apply(f).values 

       Category Weight Test Adjusted Weight 
2017-01-21 SuperMarket 0.02 NaN   0.020 
2017-01-21 SuperMarket 0.18 NaN   0.180 
2017-01-21 SuperMarket 0.71 NaN   0.710 
2017-01-21  Hotel 0.53 NaN   0.265 
2017-01-21  Hotel 0.93 0.93   1.680 
2017-01-21  Hotel 0.97 NaN   0.485 
2017-01-21   Bar 0.13 NaN   0.065 
2017-01-21   Bar 0.31 NaN   0.155 
2017-01-21   Bar 0.96 NaN   0.480 
2017-01-21   Bar 0.65 0.65   1.060 
2017-01-21   Bar 0.27 0.27   0.680 
2017-01-21   Bar 0.24 NaN   0.120 
2017-01-21  Hospital 0.65 0.65   0.650 
2017-01-21  Hospital 0.90 0.90   0.900 
2017-01-21  Hospital 1.00 1.00   1.000 
+0

這只是groupby類別?有多個日期(需要groypby日期和類別) – MysterioProgrammer91

+0

您可以將'pd.TimeGrouper'添加到group by索引中的日期。另外,我認爲您的酒吧類別的計算關閉了非na值。 –

+0

沒有值是正確的,我已經添加到問題我如何計算2017年1月21日酒吧的例子。基本上,你要在所有特定日期和類別的測試中存在價值的地點分配權重。 – MysterioProgrammer91