我有一张这样的表:
CustomerID, ProfileID, ProductID, Date, % Amount Change
1234, 4313, 41, 2013-08-01, -0.01
270, 13, 1, 2011-08-01, 10.453
8734, 3000, 5, 2014-05-01, -0.474
8734, 3000, 5, 2014-06-01, -0.619
8734, 3000, 5, 2014-07-01, -0.419
我需要在CustomerID-ProfileID-ProductID组中标记所有记录,其中%Amount Change字段中至少连续三个月为-1。
在这个例子中:
CID PID, PRID DATE % Amt Change
1234, 4313, 41, 2011-11-01, -0.414
1234, 4313, 41, 2011-12-01, -0.354
1234, 4313, 41, 2012-01-01, -0.676
1234, 4313, 41, 2012-02-01, -0.874
2313, 3311, 41, 2014-05-01, 0.5
我想标记前四个记录中的每一个并忽略第五条记录。
虽然如果我只是简单地遍历所有记录,我知道如何做到这一点,我很想知道一个Pandas的方法来做到这一点。虽然我已经读过关于" shift"和其他功能,我不完全确定如何将它们联系在一起。我想我会从这样的事情开始:
grouped = df.groupby(['CID,PID,'PRID'])
但我从那里感到困惑。
答案 0 :(得分:0)
将第一个表格中的数据用作df
,这是一种方法:
groups = df.groupby(['CustomerID','ProfileID','ProductID'])
df[groups["% Amount Change"].apply(lambda x: x < -0.01)]
的产率:
CustomerID ProfileID ProductID Date % Amount Change
2 8734 3000 5 2014-05-01 -0.474
3 8734 3000 5 2014-06-01 -0.619
4 8734 3000 5 2014-07-01 -0.419
这看起来像你想要的。
但是,如果通过简单过滤实现相同的结果,为什么还需要分组?
df[df["% Amount Change"] < -0.01]
编辑:
完全控制&#34;结果&#34;这里的数据是我的解决方案。 我稍微修改了你的数据以检查更多的情况:
data = """CustomerID,ProfileID,ProductID,Date,% Amount Change
1234, 4313, 41, 2013-12-02, -0.01
270, 13, 1, 2011-12-03, 10.453
8734, 3000, 5, 2014-12-04, 0.474
8734, 3000, 5, 2014-12-05, -0.474
8734, 3000, 5, 2014-12-06, -0.619
8734, 3000, 5, 2014-12-07, 0.620
8734, 3000, 5, 2014-12-08, -0.621
8734, 3000, 5, 2014-12-09, -0.622
8734, 3000, 5, 2014-12-10, -0.623
8734, 3000, 5, 2014-12-11, 0.623
8734, 3000, 5, 2014-12-12, -0.623
8734, 3000, 5, 2014-12-13, -0.623
8734, 3000, 5, 2014-12-14, -0.623
8734, 3000, 5, 2014-12-15, -0.419"""
df = pd.read_csv(StringIO(data))
设置过滤器级别以及序列应该是多长时间:
Filter = -0.01
ConseqN = 3
插入带有布尔值的列以指示通过过滤器的数据序列:
df['F'] = (df['% Amount Change'] < Filter).astype(int)
分批连续分组数据以确定每个数据的长度:
groups = df.groupby(['CustomerID','ProfileID','ProductID'])
df['batch'] = groups['F'].apply(lambda x: (x != x.shift()).astype(int).cumsum())
构建具有所需长度(ConseqN
)的批次列表:
groups = df[df['F']==1].groupby(['CustomerID','ProfileID','ProductID','batch'])
df[df['batch'].isin([n[3] for n, g in groups if len(g) == ConseqN])]
1批次的输出(连续3次观察):
CustomerID ProfileID ProductID Date % Amount Change F batch
6 8734 3000 5 2014-12-08 -0.621 1 4
7 8734 3000 5 2014-12-09 -0.622 1 4
8 8734 3000 5 2014-12-10 -0.623 1 4
请注意,它通过过滤器连续4次观察忽略了批次(不确定这是否真的需要,但这很容易改变)。
并且可能有一种方法可以简化流程的最后一部分,即处理捕获正确长度的批次......