我正在尝试执行一个概念上简单的任务,但我的代码似乎太昂贵了。我正在寻找一种更快捷的方式,可能会利用熊猫' 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)
这可以完成这项任务,但是很难也很慢。对不起是一个菜鸟,但我认为这可以更快地完成。有人可以提出解决方案吗?非常感谢提前。
答案 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