我将创建一个工作数据集d1
并为其分配一些新列。
iszero
跟踪其中prob
为零。稍后我会乘以此列
novist
跟踪我们visit
不是零的轨道。稍后我将乘以此值并用它来帮助创建组
filled_prob
填充1
其中prob
为零。这有助于使我的prod
函数稍后运行良好。
d1 = df.assign(
iszero=df.prob.eq(0),
novisit=df.visit.ne(0),
filled_prob=np.where(df.prob.eq(0), 1, df.prob)
)
d1
我会用我刚刚创建创建一个分组列
d1['visit_group'] = d1.groupby(['product', 'store']).novisit.cumsum()
d1
最后一列,加'cum_prob'
与我在上面制作的列。
d1['cum_prob'] = d1.groupby(
['product', 'store', 'visit_group']
).filled_prob.transform('prod') * (~d1.iszero) * (~d1.novisit)
d1
你可以切它为您的目的
d1.loc[:, df.columns.tolist() + ['cum_prob']]
一起
d1 = df.assign(
iszero=df.prob.eq(0),
novisit=df.visit.ne(0),
filled_prob=np.where(df.prob.eq(0), 1, df.prob)
)
d1['visit_group'] = d1.groupby(['product', 'store']).novisit.cumsum()
d1['cum_prob'] = d1.groupby(
['product', 'store', 'visit_group']
).filled_prob.transform('prod') * (~d1.iszero) * (~d1.novisit)
d1.loc[:, df.columns.tolist() + ['cum_prob']]
回应置评:周跳
是否不改变的计算,因为我已经奠定了。相反,我们可以预先筛选df
这样
def skip_weeks(x):
"""check if difference in week from one row
to the next is always 1. If not, then we skipped a week"""
return x.week.diff().dropna().eq(1).all()
# I'll use this to map and filter in a bit
no_skips = df.groupby(['product', 'store']).apply(skip_weeks)
# produces
# product store
# 123 301 True
# 321 True
# dtype: bool
# simple series of tuples
# could've done `df[['product', 'store']].apply(tuple, 1)`
# but this is quicker
s = pd.Series(list(zip(df['product'].tolist(), df.store.tolist())), df.index)
# filter, this is what we then use rest of algorithm on
# remember to assign it to a variable like `df = df.loc[s.map(no_skips)]`
df.loc[s.map(no_skips)]
非常感谢,你能否解释第二个最后一步。变换部分 – Mukul
[transform](http://pandas.pydata.org/pandas-docs/stable/groupby.html#transformation)返回一个对象,该对象的相同索引传递给groupby组中的'groupby'复制值。 – piRSquared
我真的不喜欢这个答案。非常复杂,难以遵循。 –