Python Pandas识别跨行的值的变化

时间:2014-11-09 22:18:03

标签: python numpy pandas

我有一张这样的表:

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'])

但我从那里感到困惑。

1 个答案:

答案 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次观察忽略了批次(不确定这是否真的需要,但这很容易改变)。

并且可能有一种方法可以简化流程的最后一部分,即处理捕获正确长度的批次......