我希望做一些类似于 here 提出的问题的事情,但在我的情况下,时间增量是 2 年,即数据是在 2008、2010、2012 年等报告的,我只想知道每个站点的开始时间戳和结束时间戳,并计算两者之间的条目数。
输入数据:
Report_Year | PWSID |
---|---|
2008-01-01 | A |
2008-01-01 | B |
2008-01-01 | C |
2008-01-01 | D |
2010-01-01 | A |
2010-01-01 | B |
2010-01-01 | C |
2012-01-01 | A |
2012-01-01 | B |
2016-01-01 | A |
这会产生一个像这样的表格:
Report_Year | PWSID | 计数 | 开始日期 | 结束日期 |
---|---|---|---|---|
2008-01-01 | A | 4 | 2008 | 2016 |
2008-01-01 | B | 3 | 2008 | 2012 |
2008-01-01 | C | 2 | 2008 | 2010 |
2008-01-01 | D | 1 | 2008 | 2008 |
我想我需要使用如下函数:
from dateutil.relativedelta import relativedelta
def yearsago(years, from_date=None):
if from_date is None:
from_date = datetime.now()
return from_date - relativedelta(years=years)
但是无法解决如何将其嵌入 groupby 函数中,就像您在这样的时间工作时可能会做的那样:
g=df.groupby('PWSID')['Report_Year'].diff().ne(pd.Timedelta(hours=1)).groupby(df['PWSID']).cumsum()
非常感谢!
答案 0 :(得分:1)
在您的情况下,数据聚合似乎更简单 - 按 PWSID 分组并在三列中收集计数、最小年份和最大年份可以这样实现:
from io import StringIO
import pandas as pd
#recreating your data frame
data1 = """Report_Year PWSID
2008-01-01 A
2008-01-01 B
2008-01-01 C
2008-01-01 D
2010-01-01 A
2010-01-01 B
2010-01-01 C
2012-01-01 A
2012-01-01 B
2016-01-01 A"""
df = pd.read_csv(StringIO(data1), delim_whitespace=True, parse_dates=["Report_Year"])
g = df.groupby("PWSID")["Report_Year"]
sum_df = g.agg(Count= "count").reset_index()
sum_df["Start_date"] = g.min().dt.year.values
sum_df["End_date"] = g.max().dt.year.values
print(sum_df)
输出:
PWSID 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
P.S.:在单独的步骤中执行此操作感觉相当乏味,因此 I asked 以获得更好的解决方案。确实有一个:
...
df = pd.read_csv(StringIO(data1), delim_whitespace=True, parse_dates=["Report_Year"])
sum_df = df.assign(Year=pd.to_datetime(df['Report_Year']).dt.year).groupby('PWSID').agg(
N=('PWSID', 'count'), Start_date=('Year', 'first'), End_date=('Year', 'last')).reset_index()
print(sum_df)