使用分位数函数

时间:2017-02-28 08:19:39

标签: python pandas group-by quantile

我想为每个日期创建一个Quantile列。计算每个唯一值Sales值的分位数。即类别总是对应于每个特定日期的销售数量。

我有按日期索引的数据框。有许多日期和多个相同的日期。 df子集的示例为1天:

          Category  Sales   Ratio 1 Ratio 2
11/19/2016  Bar     300     0.46    0.96
11/19/2016  Bar     300     0.56    0.78
11/19/2016  Bar     300     0.43    0.96
11/19/2016  Bar     300     0.47    0.94
11/19/2016  Casino  550     0.92    0.12
11/19/2016  Casino  550     0.43    0.74
11/19/2016  Casino  550     0.98    0.65
11/19/2016  Casino  550     0.76    0.67
11/19/2016  Casino  550     0.79    0.80
11/19/2016  Casino  550     0.90    0.91
11/19/2016  Casino  550     0.89    0.31
11/19/2016  Café    700     0.69    0.99
11/19/2016  Café    700     0.07    0.18
11/19/2016  Café    700     0.75    0.59
11/19/2016  Café    700     0.07    0.64
11/19/2016  Café    700     0.14    0.42
11/19/2016  Café    700     0.30    0.67
11/19/2016  Pub     250     0.64    0.09
11/19/2016  Pub     250     0.93    0.37
11/19/2016  Pub     250     0.69    0.42

我想要一个代码,它添加一个名为Quantile的新列,它为每个日期计算0.5个唯一Sales的分位数。需要注意的关键是,对于特定日期的类别,销售总是相同的(事情随着日期的变化而变化)。

解决方案示例:df ['Quantile'] = df.Sales.groupby(df.index).transform(lambda x:x.quantile(q = 0.5,axis = 0,interpolation ='midpoint'))

然而,这还不够(即使它有效)。对于此示例(对于此一个日期),在新列df ['Quantile']中,对于部分日期,所有值都相同。

对于此日期,计算将使用300,550,700和250作为分位数。

因此最终的df看起来像这样:

      Category  Sales   Ratio 1 Ratio 2     Quantile
11/19/2016  Bar     300     0.46    0.96      425
11/19/2016  Bar     300     0.56    0.78      425
11/19/2016  Bar     300     0.43    0.96      425
11/19/2016  Bar     300     0.47    0.94      425
11/19/2016  Casino  550     0.92    0.12      425
11/19/2016  Casino  550     0.43    0.74      425
11/19/2016  Casino  550     0.98    0.65      425
11/19/2016  Casino  550     0.76    0.67      425
11/19/2016  Casino  550     0.79    0.80      425
11/19/2016  Casino  550     0.90    0.91      425
11/19/2016  Casino  550     0.89    0.31      425
11/19/2016  Café    700     0.69    0.99      425
11/19/2016  Café    700     0.07    0.18      425
11/19/2016  Café    700     0.75    0.59      425
11/19/2016  Café    700     0.07    0.64      425
11/19/2016  Café    700     0.14    0.42      425
11/19/2016  Café    700     0.30    0.67      425
11/19/2016  Pub     250     0.64    0.09      425
11/19/2016  Pub     250     0.93    0.37      425
11/19/2016  Pub     250     0.69    0.42      425

如果我要在特定日期对所有销售进行分位数,而不仅仅查看每个类别中的一个元素,我会得到550(我不想要)。

关键是我希望代码简单,而且速度相当快(因为日期非常大)。插值也必须是中点。

1 个答案:

答案 0 :(得分:1)

您似乎需要drop_duplicates

df['Quantile'] = df.Sales.groupby(df.index)
                   .transform(lambda x: x.drop_duplicates().quantile())
print (df)
           Category  Sales  Ratio 1  Ratio 2  Quantile
11/19/2016      Bar    300     0.46     0.96       425
11/19/2016      Bar    300     0.56     0.78       425
11/19/2016      Bar    300     0.43     0.96       425
11/19/2016      Bar    300     0.47     0.94       425
11/19/2016   Casino    550     0.92     0.12       425
11/19/2016   Casino    550     0.43     0.74       425
11/19/2016   Casino    550     0.98     0.65       425
11/19/2016   Casino    550     0.76     0.67       425
11/19/2016   Casino    550     0.79     0.80       425
11/19/2016   Casino    550     0.90     0.91       425
11/19/2016   Casino    550     0.89     0.31       425
11/19/2016     Cafe    700     0.69     0.99       425
11/19/2016     Cafe    700     0.07     0.18       425
11/19/2016     Cafe    700     0.75     0.59       425
11/19/2016     Cafe    700     0.07     0.64       425
11/19/2016     Cafe    700     0.14     0.42       425
11/19/2016     Cafe    700     0.30     0.67       425
11/19/2016      Pub    250     0.64     0.09       425
11/19/2016      Pub    250     0.93     0.37       425
11/19/2016      Pub    250     0.69     0.42       425
df['Quantile'] = df.Sales.groupby(df.index)
                   .transform(lambda x: np.percentile(x.unique(), 50))
print (df)
           Category  Sales  Ratio 1  Ratio 2  Quantile
11/19/2016      Bar    300     0.46     0.96       425
11/19/2016      Bar    300     0.56     0.78       425
11/19/2016      Bar    300     0.43     0.96       425
11/19/2016      Bar    300     0.47     0.94       425
11/19/2016   Casino    550     0.92     0.12       425
11/19/2016   Casino    550     0.43     0.74       425
11/19/2016   Casino    550     0.98     0.65       425
11/19/2016   Casino    550     0.76     0.67       425
11/19/2016   Casino    550     0.79     0.80       425
11/19/2016   Casino    550     0.90     0.91       425
11/19/2016   Casino    550     0.89     0.31       425
11/19/2016     Cafe    700     0.69     0.99       425
11/19/2016     Cafe    700     0.07     0.18       425
11/19/2016     Cafe    700     0.75     0.59       425
11/19/2016     Cafe    700     0.07     0.64       425
11/19/2016     Cafe    700     0.14     0.42       425
11/19/2016     Cafe    700     0.30     0.67       425
11/19/2016      Pub    250     0.64     0.09       425
11/19/2016      Pub    250     0.93     0.37       425
11/19/2016      Pub    250     0.69     0.42       425