熊猫在一列上分组,另一列上的最大日期python

Posted

技术标签:

【中文标题】熊猫在一列上分组,另一列上的最大日期python【英文标题】:Pandas group by on one column with max date on another column python 【发布时间】:2018-07-23 01:40:58 【问题描述】:

我有一个包含以下数据的数据框:

invoice_no  dealer  billing_change_previous_month        date
       110       1                              0  2016-12-31
       100       1                         -41981  2017-01-30
      5505       2                              0  2017-01-30
      5635       2                          58730  2016-12-31

我希望只有一个经销商的最大日期。所需的输出应该是这样的:

invoice_no  dealer  billing_change_previous_month        date
       100       1                         -41981  2017-01-30
      5505       2                              0  2017-01-30

每个经销商的最大日期应该是不同的, 提前感谢您的帮助。

【问题讨论】:

你如何定义最大日期? @JosephBudin 最大日期是最新日期。例如:如果我们比较 2016-12-31 和 2017-01-30 ,最大日期是 2017-01-30。 【参考方案1】:

您可以通过 groupby 和 transform 使用布尔索引

df_new = df[df.groupby('dealer').date.transform('max') == df['date']]

    invoice_no  dealer  billing_change_previous_month   date
1   100         1       -41981                          2017-01-30
2   5505        2       0                               2017-01-30

即使有两个以上的经销商,该解决方案也能按预期工作(以解决 Ben Smith 提出的问题),

df = pd.DataFrame('invoice_no':[110,100,5505,5635,10000,10001], 'dealer':[1,1,2,2,3,3],'billing_change_previous_month':[0,-41981,0,58730,9000,100], 'date':['2016-12-31','2017-01-30','2017-01-30','2016-12-31', '2019-12-31', '2020-01-31'])

df['date'] = pd.to_datetime(df['date'])
df[df.groupby('dealer').date.transform('max') == df['date']]


    invoice_no  dealer  billing_change_previous_month   date
1   100         1       -41981                          2017-01-30
2   5505        2       0                               2017-01-30
5   10001       3       100                             2020-01-31

【讨论】:

谢谢@Vaishali 你能解释一下 (== df['date']) 是做什么的吗? transform 不会改变数据框的形状,这与聚合的 groupby 不同。所以 df.groupby('dealer').date.transform('max') 会给你一个日期系列,每个经销商的最大日期。现在您将此系列与您的日期列进行比较,该列将返回一个布尔系列。将布尔系列传递给 df,您将获得条件系列 == df['date'] 为真的行。 此方法仅适用于只有两个不同经销商的特殊情况,但考虑有许多经销商和许多不同日期的情况。此方法天真地检查整个数据帧的最大日期以制作布尔系列。因此,当您将布尔序列传递给整个数据帧时,它只会检查所有日期的最大日期是否存在于数据帧中,并且会导致大量数据丢失。我认为这不是我们想要的。【参考方案2】:

这里https://***.com/a/41531127/9913319是更正确的解决方案:

df.sort_values('date').groupby('dealer').tail(1)

【讨论】:

【参考方案3】:

Tack 1

在使用drop_duplicates 之前按经销商和日期排序。这对下面 Tack 2 中出现的问题视而不见,因为在此方法中每个经销商不可能有多个记录。这对您来说可能是也可能不是问题,具体取决于您的数据和用例。

df.sort_values(['dealer', 'date'], inplace=True)
df.drop_duplicates(['dealer', 'date'], inplace=True)

Tack 2

这是使用groupby 和merge 的更糟糕的方法。使用groupby 查找每个经销商的最大日期。我们使用how='inner' 参数仅包含出现在包含每个经销商的最大日期的 groupby 对象中的那些经销商和日期组合。

但是,请注意,如果最大日期在原始表中重复,这将返回每个经销商的多条记录。根据您的数据和用例,您可能需要使用 drop_duplicates。

df.merge(df.groupby('dealer')['date'].max().reset_index(), 
                             on=['dealer', 'date'], how='inner')

   invoice_no  dealer  billing_change_previous_month        date
0         100       1                         -41981  2017-01-30
1        5505       2                              0  2017-01-30

【讨论】:

以上是关于熊猫在一列上分组,另一列上的最大日期python的主要内容,如果未能解决你的问题,请参考以下文章

在按两列分组时选择最大值,并在另一列上排序

内连接恰好在一列上,而在另一列上模糊

在一列上排名表,同时在另一列上排序

基于另一列的最大值的列上的 SQL 内连接 [重复]

将列上的纪元时间保存到另一列 postgres

选择一列上的值在另一列上具有相同的一组值