【问题标题】:How to select rows by group if years are next to each other in pandas dataframe?如果熊猫数据框中的年份彼此相邻,如何按组选择行?
【发布时间】:2020-07-25 19:19:57
【问题描述】:

我有一个看起来像这样的熊猫数据框:

pd.DataFrame({'a':['cust1', 'cust1', 'cust2', 'cust3', 'cust3', 'cust4', 'cust4'],
                   'date':[date(2019, 1, 20), date(2020, 6, 15), date(2017, 1, 10), date(2015, 6, 12), date(2017, 12, 15), date(2018, 12, 10), date(2017, 1, 5)]
                   })

       a        date
0  cust1  2019-01-20
1  cust1  2020-06-15
2  cust2  2017-01-10
3  cust3  2015-06-12
4  cust3  2017-12-15
5  cust4  2018-12-10
6  cust4  2017-01-05

如果“日期”列中的年份是“背靠背”或彼此相邻(即年份之间没有间隔)并且至少有 2 个不同的年份,我想在“a”列中按组选择所有行“a”中每组的日期。

生成的数据框应如下所示。

       a        date
0  cust1  2019-01-20
1  cust1  2020-06-15
5  cust4  2018-12-10
6  cust4  2017-01-05

解释:未选择第 2 行,因为组“cust2”只有 1 年/日期。组 'cust3' 未被选中,因为 2015 年和 2017 年之间存在“差距”。

【问题讨论】:

  • 为什么不在结果中包含第 4 行(即使它来自第 5 行的连续一年)?是不是因为它来自与第 5 行不同的组?
  • 是的。我只想在组内查看

标签: python pandas dataframe pandas-groupby


【解决方案1】:

date 列转换为pandas 日期时间序列,然后使用Series.groupbya 列上的year 进行分组,并使用diff 获得连续差异,然后使用shift + ffill,以及最后使用abs + Series.eq 创建一个布尔掩码m,使用这个掩码过滤行:

df['date'] = pd.to_datetime(df['date'])
m = df['date'].dt.year.groupby(df['a']).apply(lambda x: x.diff().shift(-1).ffill()).abs().eq(1)
df1 = df[m]

结果:

print(df1)
       a       date
0  cust1 2019-01-20
1  cust1 2020-06-15
5  cust4 2018-12-10
6  cust4 2017-01-05

【讨论】:

  • 不错的解决方案。我可以不戴面具做 1 衬里吗?
  • 可以,但是看起来不太好看,而且会影响可读性..
  • 如果前三个日期(全部来自 cust1)是 date(2015, 6, 15), date(2019, 1, 20), date(2020, 6, 15),则此解决方案将不起作用),
【解决方案2】:

这是一个使用groupbyshift 的解决方案,为了清楚起见分几个步骤:

df["year"] = pd.to_datetime(df.date).dt.year
df["adjacent"] = (df.groupby("a")["year"].diff().abs() == 1) | (df.groupby("a")["year"].diff(-1).abs() == 1)
res = df[df.adjacent]

输出:

       a       date  year    adjacent
0  cust1 2019-01-20  2019    True
1  cust1 2020-06-15  2020    True
5  cust4 2018-12-10  2018    True
6  cust4 2017-01-05  2017    True

【讨论】:

  • 这能回答你的问题吗?
猜你喜欢
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
  • 2022-07-06
  • 2021-08-08
  • 2016-09-01
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
相关资源
最近更新 更多