日期时间列的简化 pandas groupby 聚合[重复]

Posted

技术标签:

【中文标题】日期时间列的简化 pandas groupby 聚合[重复]【英文标题】:Simplified pandas groupby aggregation for datetime column [duplicate] 【发布时间】:2021-05-17 17:36:14 【问题描述】:

我有这个带有日期时间、整数和字符串列的 pandas 数据框

from io import StringIO
import pandas as pd
data1 =  """Year        N   X
            2008-01-01  2   A
            2008-01-01  3   B
            2008-01-01  6   C
            2008-01-01  2   D
            2010-01-01  7   A
            2010-01-01  1   B
            2010-01-01  8   C
            2012-01-01  9   A
            2012-01-01  4   B
            2016-01-01  1   A"""

df = pd.read_csv(StringIO(data1), delim_whitespace=True, parse_dates=["Year"])

我可以简单地将列 N 聚合为计数、最小值和最大值:

df1 = df.groupby("X")["N"].agg(Count="count", Min="min", Max="max").reset_index()
print(df1)

   X  Count  Min  Max
0  A      4    1    9
1  B      3    1    4
2  C      2    6    8
3  D      1    2    2

对于仅显示年份的列Year 有没有办法实现相同的效果? 我可以通过几个步骤来做到这一点:

g = df.groupby("X")["Year"]
df2 = g.agg(Count= "count").reset_index()
df2["Start_date"] = g.min().dt.year.values
df2["End_date"] = g.max().dt.year.values
print(df2)

   X  Count  Start_date  End_date
0  A      4        2008      2016
1  B      3        2008      2012
2  C      2        2008      2010
3  D      1        2008      2008

但与上面N类似的版本如

df2 = df.groupby("X")["Year"].agg(Count="count", Min="min().dt.year.values", Max="max().dt.year.values").reset_index()

显然不起作用。有没有更简单的方法来聚合 pandas groupby 中的第一年和最后一年(除了如上所述首先提取最小/最大日期,然后将日期时间列转换为年份列的明显方法)?

【问题讨论】:

【参考方案1】: named aggregations lambda 日期系列函数
df = pd.read_csv(io.StringIO("""Year        N   X
            2008-01-01  2   A
            2008-01-01  3   B
            2008-01-01  6   C
            2008-01-01  2   D
            2010-01-01  7   A
            2010-01-01  1   B
            2010-01-01  8   C
            2012-01-01  9   A
            2012-01-01  4   B
            2016-01-01  1   A"""), sep="\s+")
df.Year = pd.to_datetime(df.Year)

df = df.groupby("X").agg(N=("N","count"),
                    Start_date=("Year",lambda f: min(f.dt.year)),
                    End_date=("Year",lambda f: max(f.dt.year)))

X N Start_date End_date
A 4 2008 2016
B 3 2008 2012
C 2 2008 2010
D 1 2008 2008

【讨论】:

不错。以前从未遇到过命名聚合。【参考方案2】:

您是否尝试过将 GroupBy.agg 与命名聚合一起使用?

df.assign(Year=pd.to_datetime(df['Year']).dt.year).groupby('X').agg(
    N=('N', 'count'), Start_date=('Year', 'first'), End_date=('Year', 'last'),)

   N  Start_date  End_date
X                         
A  4        2008      2016
B  3        2008      2012
C  2        2008      2010
D  1        2008      2008

如果日期不是升序,请分别使用 'min''max' 而不是 'first''last'

这种方式可以让您避免在 grouper 中使用 lambda 表达式(所以这是非常高效的)。更多关于命名聚合的信息可以在我的帖子here中找到。

【讨论】:

我认为您有权单独关闭我的问题作为“命名聚合”问题的副本。看来这就是它归结为的原因。 我个人认为有不止一种方法来问同样的事情很好,特别是如果你已经做出了诚实的努力并在最后一英里寻求帮助。所以无论哪种方式,我都没有强烈的偏好。但是,既然您似乎不介意,并且由于链接的骗子无论如何都有我的答案,我想我会继续为您关闭它:p

以上是关于日期时间列的简化 pandas groupby 聚合[重复]的主要内容,如果未能解决你的问题,请参考以下文章

执行 pandas groupby 操作的更快替代方案

具有多索引列的 Pandas groupby

如何通过另一列的值 pandas 聚合 groupBy [重复]

Python Pandas 使用日期时间数据按日期分组

将列的名称保留在 groupby 中,并在 pandas 数据框中使用 sum

groupby pandas:插入列的索引与框架索引不兼容