【问题标题】:How to Get overlapping Records for a particular group in Pandas Dataframe如何在 Pandas Dataframe 中获取特定组的重叠记录
【发布时间】:2021-10-20 09:11:24
【问题描述】:

我有一个 csv 文件(用“|”分隔),其中的数据如下:

|origin|destination|class|eff_start_date|eff_end_date|price
0|A|B|1|2016-01-01|2016-12-31|37.4
1|A|B|2|2016-01-01|2016-12-31|30.4
2|A|C|1|2016-01-01|2016-12-31|94.0
3|A|C|2|2016-01-01|2016-12-31|80.0
4|A|B|1|2017-01-01|2017-12-31|38.4
5|A|B|2|2017-01-01|2017-12-31|31.4
6|A|C|1|2017-01-01|2017-12-31|95.0
7|A|C|2|2017-01-01|2017-12-31|81.0
8|A|C|2|2017-02-01|2017-05-20|82.0

此文件提供特定出发地、目的地的票价。 eff_start_date & eff_end_date 显示特定票价的有效期。

我正在编写代码来验证此文件,以确保任何日期都不应该有 2 个单独的票价值。在上面的示例中,记录 7 和 8 对于相同的出发地、目的地和舱位存在冲突,在 2017 年 2 月至 2017 年 5 月 20 日之间可能有 2 个单独的票价记录。

以下是我的代码的 sn-p,但它不起作用,我无法找出问题所在。

import pandas as pd

df_fares = pd.read_csv('input.csv', sep='|')
df_fares.eff_start_date = pd.to_datetime(df_fares.eff_start_date, format='%Y-%m-%d')
df_fares.eff_end_date = pd.to_datetime(df_fares.eff_end_date, format='%Y-%m-%d')
df_fares['overlap'] = (df_fares.groupby(['origin', 'destination', 'class'])
            .apply(lambda x: (x['eff_start_date'].shift() - x['eff_end_date']) > timedelta(0))
            .reset_index(drop=True))

【问题讨论】:

  • 我不明白逻辑 - origin,destinationclass 组合不允许重复或..?
  • 它们可以重复,但不能用于重叠的日期范围。

标签: python pandas dataframe date


【解决方案1】:

我认为你把班次放在了错误的位置。然后,这将指出前一行的结束日期和当前行的开始日期“重叠”的行。

import pandas as pd
from datetime import timedelta

df_fares = pd.read_csv('input.csv', sep='|')
df_fares.eff_start_date = pd.to_datetime(df_fares.eff_start_date, format='%Y-%m-%d')
df_fares.eff_end_date = pd.to_datetime(df_fares.eff_end_date, format='%Y-%m-%d')
df_fares['overlap'] = (df_fares.groupby(['origin', 'destination', 'class'])
                           .apply(lambda x: x['eff_start_date'] - x['eff_end_date'].shift() < timedelta(0))
                            .reset_index(drop=True))

但要小心,这还不是全部。您的行没有排序,这意味着评估取决于数据框的加载方式。也许值得看看这些想法:Efficient date range overlap calculation in python?

还有一个问题:

绝不是 2 个单独的票价值

您需要检查这些值是否相同。您可以通过删除所有行来做到这一点,无论如何在添加overlap 列之前这对您来说都很好:

df_fares = df_fares.drop_duplicates(subset=['origin', 'destination', 'class', 'price'])

【讨论】:

  • 这不起作用。我仍然在重叠列上弄错了
  • 代码应该为您提供除最后一行之外的所有行的输出False 8|A|C|2|2017-02-01|2017-05-20|82.0 应该是True。这不适合你吗?
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2013-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
相关资源
最近更新 更多