python - Pandas:标记重叠日期,但如果满足条件则排除某些行

标签 python pandas iteration

我有一个棘手的问题无法解决。我有数百万行,需要标记当前行和上一行之间的重叠日期。这些行按“KEY”分组,在该分组中,我需要标记具有“Date1”的行,该行与上一行的“Date2”重叠。

重叠行是指第二行的 Date1 小于前一行的 Date2,并且第二行的 Date1 大于或等于前一行的 Date1。

简单地说:如果第二行的 date1 介于前一行的 date1 和 date2 之间,则将这两行标记为重叠行。仅供引用,在任何给定行上,Date1 永远不会大于 Date2。

上一行日期 1 <= 第二行日期 1 < 上一行日期 2

我不明白的困难部分是这一步需要按顺序执行。也就是说,如果该分组中的第二行被标记,则该组中的下一行(第 3 行)将与第一行进行比较(在这种情况下,第一行也将被标记为与第 2 行重叠)。

这是一个数据集:

df = pd.DataFrame({'KEY': ['100000003', '100000009', '100000009', '100000009', '100000009','100000034','100000034', '100000034'], 
              'Date1': [20120506, 20120506, 20120507,20120608,20120620,20120206,20120304,20120405],
              'Date2': [20120528, 20120610, 20120615,20120629,20120621,20120305,20120506,20120506]})
df['Date1'] = pd.to_datetime(df["Date1"], format='%Y%m%d')
df['Date2'] = pd.to_datetime(df["Date2"], format='%Y%m%d')
df.sort_values(by=['KEY','Date1','Date2'], inplace=True)
df[['KEY','Date1','Date2']]

    KEY         Date1       Date2
0   100000003   2012-05-06  2012-05-28
1   100000009   2012-05-06  2012-06-10
2   100000009   2012-05-07  2012-06-15
3   100000009   2012-06-08  2012-06-29
4   100000009   2012-06-20  2012-06-21
5   100000034   2012-02-06  2012-03-05
6   100000034   2012-03-04  2012-05-06
7   100000034   2012-04-05  2012-05-06

由于有数百万行,并且每个组的大小各不相同,因此我编写了一个 for 循环,它只会迭代最大数量的 groupby KEY。

for item in range(df.groupby('KEY')['KEY'].count().max()):
    df['PrevDate1'] = df.groupby('KEY')['Date1'].shift(1)
    df['PrevDate2'] = df.groupby('KEY')['Date2'].shift(1)
    df['Overlapping_Hospitalizations'] = np.where(df['Date1'].between(df['PrevDate1'],df['PrevDate2']),'Y','N')
    print("DONE")
df

这适用于之前的每个 KEY,但我还需要它与导致该分组重叠的初始 KEY 进行比较。

预期结果:

    KEY         Date1       Date2       OverlappingFlag
0   100000003   2012-05-06  2012-05-28     N
1   100000009   2012-05-06  2012-06-10     Y
2   100000009   2012-05-07  2012-06-15     Y
3   100000009   2012-06-08  2012-06-29     Y
4   100000009   2012-06-20  2012-06-21     Y
5   100000034   2012-02-06  2012-03-05     Y
6   100000034   2012-03-04  2012-05-06     Y
7   100000034   2012-04-05  2012-05-06     Y

编辑:两个重叠的行都需要标记。查看预期结果。

最终答案:

for item in range(df.groupby('KEY')['KEY'].count().max()):
    df['overlap'] = (((df['KEY'] == df['KEY'].shift())   & \
                  (df['Date1'] >= df['Date1'].shift(1))  & \
                  (df['Date1'] < df['Date2'].shift(1)))  | \
                 ((df['KEY'] == df['KEY'].shift(-1))     & \
                  (df['Date1'].shift(-1) >= df['Date1']) & \
                  (df['Date1'].shift(-1) < df['Date2'])))

最佳答案

看起来问题中的预期结果不符合定义:

The rows are grouped by 'KEY' and within this grouping I need to flag rows that have 'Date1' which overlaps with the 'Date2' of the previous row.

    KEY         Date1       Date2       OverlappingFlag
0   100000003   2012-05-06  2012-05-28     N
1   100000009   2012-05-06  2012-06-10     Y  # probably not
2   100000009   2012-05-07  2012-06-15     Y
3   100000009   2012-06-08  2012-06-29     Y
4   100000009   2012-06-20  2012-06-21     Y
5   100000034   2012-02-06  2012-03-05     Y  # probably not
6   100000034   2012-03-04  2012-05-06     Y
7   100000034   2012-04-05  2012-05-06     Y

本例中 @Evan 代码的扩展:

import pandas as pd
import numpy as np

df = pd.DataFrame({'KEY': ['100000003', '100000009', '100000009', '100000009', '100000009','100000034','100000034', '100000034'], 
              'Date1': [20120506, 20120506, 20120507,20120608,20120620,20120206,20120304,20120405],
              'Date2': [20120528, 20120610, 20120615,20120629,20120621,20120305,20120506,20120506]})
df['Date1'] = pd.to_datetime(df["Date1"], format='%Y%m%d')
df['Date2'] = pd.to_datetime(df["Date2"], format='%Y%m%d')
df.sort_values(by=['KEY','Date1','Date2'], inplace=True)
# if KEY is already an index, df = df.reset_index()
# df.set_index('KEY', inplace = True)

# this is really the only part changed
df['overlap'] = ((df.KEY == df.KEY.shift()) & \
    (df.Date1 < df.Date2.shift())) | \
    ((df.KEY == df.KEY.shift(-1)) & \  
    (df.Date2 < df.Date1.shift(-1)))

df.set_index('KEY', inplace = True)

关于python - Pandas:标记重叠日期,但如果满足条件则排除某些行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48671669/

相关文章:

python - 如何为 AWS Lambda 捆绑 Python

python - 使用 groupby 在 Pandas 中创建字典

python - 如何按不在数据框中的数组对数据框进行排序

python - 如何更改 Matplotlib 表格中文本的字体类型?

python - 如何在Kafka中处理一次消息,以便服务重新启动时不会处理所有消息

python - 从 Pandas 数据框列更新 slqalchemy orm 列的正确方法是什么

javascript - 迭代数组 : another approach

python - 迭代时附加到列表

java - 了解 Java 迭代器

python - 微调 mnist 深度自动编码器模型