使用分位数函数在 pandas 分位数中创建新列

Creating a new column in pandas quantile using Quantile function

我想为每个日期创建一个分位数列。计算每个唯一值销售额的分位数。即类别始终对应于每个特定日期的相同销售额。

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

          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 分位数。需要注意的关键是特定日期的类别销售额始终相同(情况会随着日期的变化而变化)。

解决方案示例:df['Quantile'] = df.Sales.groupby(df.index).transform(lambda x: x.quantile(q=0.5, axis=0 , 插值='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(我不想要)。

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

看来你需要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