从大熊猫组获得四分位数范围和中位数,所有未提及日期的零填充

时间:2018-05-25 12:03:52

标签: python pandas dataframe padding iqr

我有一个数据帧(除了我的非常大):

user1      user2   day   hour  quantity
-------------------------------------
Alice      Bob      1     12     250
Alice      Bob      1     13     250
Bob        Carol    1     10     20
Alice      Bob      4     1      600
.
.
.

...然后假设我得到以下groupby和聚合(user1user2day):

user1      user2   day   quantity
---------------------
Alice      Bob      1      500
                    4      600
Bob        Carol    1      20
                    3      100

其中日期应为0-364(365天)。我想要的是所有日子中每个用户的计数的四分位数范围(和中位数) - 除了零不计算

如果我对所有被排除的日子都有明确的零,那么生活会更容易:

user1    user2    day   quantity
---------------------
Alice    Bob      1      500
                  2      0
                  3      0
                  4      600
.....
Bob      Carol    1      20
                  2      0
                  3      100
...

...因为那时我可以做df.reset_index().agg({'quantity':scipy.stats.iqr})但是我正在处理一个非常大的数据帧(上面的例子是虚拟的),并且用零重建索引是不可能的。

我知道怎么做:因为我知道有365天,所以我应该用零填充剩下的数字:

Alice-Bob: [500,600] + (365-2) * [0]

并获得scipy.stats.iqr(和中位数)。但是,这将涉及迭代所有user1-user2对。从经验来看,这需要花费很多时间。

有没有任何矢量化解决方案?我也必须得到中位数,我认为应该采用相同的方法。

1 个答案:

答案 0 :(得分:1)

要利用零而不将它们放在数据框中,您可以使用以下内容:

test = df.groupby(['user1', 'user2', 'day'])['quantity'].mean().reset_index()\
         .groupby(['user1', 'user2'])\
         .agg({'day': lambda x: tuple(x), 'quantity': lambda x: tuple(x)})\
         .reset_index()

def med_from_tuple(row):
    # starts with everything zero, and replaces some with the nonzero values in the dataframe
    z = np.zeros(365)
    np.put(z, row['day'], row['quantity'])
    return np.median(z)

test['example'] = test.apply(lambda x: med_from_tuple(x), axis=1)

这将创建数量的中位数,就像数据框中有零一样。

test
#   user1  user2     day    quantity   example
#0  Alice    Bob  (1, 4)  (250, 600)       0.0
#1    Bob  Carol    (1,)       (20,)       0.0