确定占总数90%的记录

时间:2018-10-06 18:59:01

标签: python pandas pandas-groupby

我有一份报告,确定了总体数字/趋势的关键驱动因素。我想自动化该功能,以便能够基于该数字的百分比列出/识别基础记录。例如,如果在南部(地区)的小部件销售净变化为-5,000.00,但有正反两面,则-我想找出构成这一点的所有潜在驱动因素中的至少约90%(-4,500.00)-从最大到最小共计5,000.00。

data

region    OfficeLocation  sales
South     1                -500
South     2                300
South     3                -1000
South     4                -2000
South     5                 300
South     6                -700
South     7                -400
South     8                 800
North     11                300
North     22               -400
North     33                1000
North     44                800
North     55                900
North     66                -800

对于南方,总销售额是-3200。我想识别/列出构成此举动至少90%的驱动程序(降序)-因此-3200的90%将是2880。并且南办公室3和4的定向移动/销售= -3000将是此请求的输出:

region    OfficeLocation  sales
South     3                -1000
South     4                -2000

对于北,总销售额为+1800。我想识别/列出构成此举动至少90%(按降序排列)的驱动程序-因此1800的至少90%将是1620。并且南办公室3和4的定向动向/销售=- 3000将是此请求的输出:

地区办事处位置销售     北33 1000     北44800

以上数据集对南/北都有正反两方面的趋势。您能提供的任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

如评论中所述,目前尚不清楚在'North'情况下该怎么做,因为那里的总和为正,但是忽略这一点,您可以执行以下操作:

In [200]: df[df.groupby('region').sales.apply(lambda g: g <= g.loc[(g.sort_values().cumsum() > 0.9*g.sum()).idxmin()])]
Out[200]:
   region  OfficeLocation  sales
2   South               3  -1000
3   South               4  -2000
13  North              66   -800

如果在积极的情况下,您希望找到尽可能少的元素,这些元素在一起构成其销售额的90%,则可以采用以下解决方案:

def is_driver(group):
    s = group.sum()
    if s > 0:
        group *= -1
        s *= -1
    a = group.sort_values().cumsum() > 0.9*s
    return group <= group.loc[a.idxmin()]

In [168]: df[df.groupby('region').sales.apply(is_driver)]
Out[168]:
   region  OfficeLocation  sales
2   South               3  -1000
3   South               4  -2000
10  North              33   1000
12  North              55    900

请注意,在平局的情况下,只会选择一个元素。