我有这个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
的count、min和max简单地聚合为:
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中的第一年和去年(除了像上面那样首先提取最小/最大日期的明显方法,然后将datetime列转换为年份列)?
- 命名聚合
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)))
您是否尝试使用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表达式(因此这是非常高性能的)。更多关于命名聚合的信息可以在我的文章中找到。