Python:在pandas GroupBy对象上有效地使用apply

时间:2016-04-17 19:52:15

标签: python pandas dataframe group-by

我正在尝试执行一个概念上简单的任务,但我的代码似乎太昂贵了。我正在寻找一种更快捷的方式,可能会利用熊猫' GroupBy对象的内置函数。

起点是一个名为price的DataFrame,其中列= [[' item',' store',' day',' price&# 39;]],其中每个observatoin是特定于商品商店组合的最新价格更新。问题是某些价格更新与同一商品 - 商店组合的最后一次价格更新相同。例如,让我们看看一个特定的部分:

       day  item_id  store_id  price
35083   34    85376       211   5.95
56157   41    85376       211   6.00
63628   50    85376       211   5.95
64955   51    85376       211   6.00
66386   56    85376       211   6.00
69477   69    85376       211   5.95

在这个例子中,我希望观察到的天数等于56(因为价格与该组中的最后一次观察相同)。我的代码是:

def removeSameLast(df):

    shp = df.shape[0]
    lead = df['price'][1:shp]
    lag = df['price'][:shp-1]
    diff = np.array(lead != lag)

    boo = np.array(1)
    boo = np.append(boo,diff)
    boo = boo.astype(bool)

    df = df.loc[boo]

    return df

gCell = prices.groupby(['item_id', 'store_id'])
prices = gCell.apply(removeSameLast)

这可以完成这项任务,但是很难也很慢。对不起是一个菜鸟,但我认为这可以更快地完成。有人可以提出解决方案吗?非常感谢提前。

1 个答案:

答案 0 :(得分:1)

我建议使用Pandas的shift函数寻找一个简单的解决方案。这将删除groupby和函数调用的使用。

我们的想法是查看系列[5.95, 6, 5.95, 6, 6, 5.95]等于移位的[nan, 5.95, 6, 5.95, 6, 6],并删除(或者不选择)发生此情况的行。

>>> mask = ~np.isclose(prices['price'], prices['price'].shift())
>>> prices[mask]
       day  item_id store_id    price
35083   34    85376      211    5.95
56157   41    85376      211    6.00
63628   50    85376      211    5.95
64955   51    85376      211    6.00
69477   69    85376      211    5.95

简单基准:

%timeit prices = gCell.apply(removeSameLast)
100 loops, best of 3: 4.46 ms per loop

%timeit mask = df.price != df.price.shift()
1000 loops, best of 3: 183 µs per loop