如何根据条件比较连续的行并添加列

时间:2018-08-29 18:39:02

标签: python-3.x pandas-groupby

我正在尝试计算pandas数据帧中两个连续行之间的差,并根据结果想为列填充一些值。

例如:

以下是示例数据

ID Date
1   2/2/2018
2   2/3/2018
3   2/18/2018
3   2/19/2018
3   2/27/2018
4   5/5/2018
4   6/9/2018
5   6/10/2018
6   7/1/2018
6   7/2/2018
6   7/10/2018
6   7/30/2018
6   8/1/2018
6   8/3/2018
7   8/10/2018

数据按ID分组。

下面是示例输出数据

enter image description here

因此,每当ID更改时,“代码”列将具有“ I”。对于相同的ID,如果两个连续日期之间的差值小于30,则“代码”列为“ R1”;对于相同的ID,如果下一个日期在上一个“代码”的30天之内,则为“ R2”,如果下一个数据位于上一个“代码”的30天内,则相同的ID将具有“ R4”。例如,假设案例ID为“ 4”,则“代码”的两行均为“ I”,因为即使ID = 4,两个日期也相距30天以上。 6/9/2018-5/5/2018 = 34.

sorted_data["Code"] = "I"
def conditions(data):
    if data['Completed Date'].diff() <=30:
        val = "R1"
    elif  data['Completed Date'].diff() <=30:
        val = "R2"
    elif  data['Completed Date'].diff() <=30:
        val = "R3"
    elif data['Completed Date'].diff() <=30:
        val = "R4"
    elif data['Completed Date'].diff() <=30:
        val = "R5"
    elif data['Completed Date'].diff() <=30:
        val = "R6"
    elif data['Completed Date'].diff() <=30:
        val = "R7"
    elif data['Completed Date'].diff() <=30:
        val = "R8"
    return val
for groups, data in sorted_data.groupby("Cust_No"):
    print(conditions(sorted_data))

我不知道如何获取下一行的值来比较日期。上面的代码无法正常工作,并给我错误。

2 个答案:

答案 0 :(得分:1)

可能不是最佳选择,但可以使用迭代程序:

prev_id = 'x' 
prev_date = pd.to_datetime('1/1/1900')
prev_rpt = 0
for idx,ser in df.iterrows():
    if ser.ID == prev_id and (ser.Date - prev_date).days < 30:
        prev_rpt += 1
        df.loc[idx,'Code'] = 'R' + str(prev_rpt)
    else:
        df.loc[idx,'Code'] = 'I'
        prev_rpt = 0
    prev_id = ser.ID
    prev_date = ser.Date  

答案 1 :(得分:1)

ID分组,找到与前一个日期的日期差小于或等于30的所有行。

然后再次按ID分组,获得累加和并设置I,其中值等于0,否则以R前缀

x = df.groupby('ID').apply(lambda x: x.Date-x.Date.shift() <= pd.Timedelta(days=30)).astype(int) 
df['out'] = x.groupby('ID').cumsum().apply(lambda x: 'I' if x == 0 else f'R{x}').reset_index(drop=True)  

# output:

    ID       Date out
0    1 2018-02-02   I
1    2 2018-02-03   I
2    3 2018-02-18   I
3    3 2018-02-19  R1
4    3 2018-02-27  R2
5    4 2018-05-05   I
6    4 2018-06-09   I
7    5 2018-06-10   I
8    6 2018-07-01   I
9    6 2018-07-02  R1
10   6 2018-07-10  R2
11   6 2018-07-30  R3
12   6 2018-08-01  R4
13   6 2018-08-03  R5
14   7 2018-08-10   I