我正在尝试计算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分组。
下面是示例输出数据
因此,每当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))
我不知道如何获取下一行的值来比较日期。上面的代码无法正常工作,并给我错误。
答案 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