如何从数据帧中获取每个月的最后一天,并从数据帧中删除其余日期?

2024-10-03 06:22:33 发布

您现在位置:Python中文网/ 问答频道 /正文

enter image description here

大家好, 该图像是我学习python的数据框架

从这个数据框中,我试图找到每年12月最后一天的行记录。我的目标是在数据框中以黄色突出显示记录,并删除白色行

例如,对于2010年,我只想保留第三条记录并删除第1到第2行。 至于2011年,我想删除第4行到第7行,保留第8行

下面是我写的代码。我打算使用loop查找我想要保留的记录,并删除其余的记录

为了使用月值保留记录,我通过保留12月和删除1月到11月的记录来实现我的目标

然而,有好几天(最后3行代码),我意识到最后一天并不总是以数据帧中的31结尾,我不能使用我的初始逻辑来删除

我是否可以寻求帮助,如果有更好的解决方案,找到数据帧中的最后一天,并删除其余的

谢谢

amalgamate=pd.read_excel("amalgamate.xlsx")

##Create last 3 columns to segregate Year, Month and Day.
amalgamate["Date"] = pd.to_datetime(amalgamate["Date"], errors = "raise", format = "%Y-%m-%d")
amalgamate["Year"]=amalgamate["Date"].dt.year
amalgamate["Month"]=amalgamate["Date"].dt.month
amalgamate["Day"]=amalgamate["Date"].dt.day


listofMonth=amalgamate.Month.unique()
listofDay=amalgamate.Day.unique()

#Loop through the records and remove records that are not Dec for each year
for eachmonth in listofMonth:
    if eachmonth !=12:
        amalgamate=amalgamate[amalgamate.Month != eachmonth]
        
#Loop through the records and remove records that are not 31 for each month
for eachday in listofDay:
    if eachday !=31:
        amalgamate=amalgamate[amalgamate.Day != eachday]

Tags: and数据代码目标fordate记录dt
3条回答

您可以使用pandas groupby查找每年的最后一个月(即最大)和最后一天,然后合并数据帧以仅筛选包含最后一个月和最后一天的行。正如您不必假设数据中12月的最后一天是31日一样,您也不必假设数据中一年的最后一个月是12月。有多种方法可以做到这一点,您可以按不同的顺序执行以下步骤。以下是我认为最容易遵循的一条:

row1list = [2010, 12, 28]
row2list = [2010, 12, 20]

row3list = [2011, 11, 20]
row4list = [2011, 11, 15]
row5list = [2011, 10, 30]
df = pd.DataFrame([row1list, row2list, row3list, row4list, row5list], columns=['year', 'month', 'day'])

# find last day for every combo of year, month
df_last_day_per_year_month = df.groupby(['year', 'month'], as_index=False).agg({
    'day': max})

# find last month for every year, using only the rows with max day per year, month 
df_last_month_per_year = df_last_day_per_year_month.groupby('year', as_index=False).agg({
    'month': max})

# keep only the last month by comparing month values to last month per year
df_last_month_per_year = df_last_month_per_year.rename(columns={'month':'last_month'})

df_last_day_per_year_month = df_last_day_per_year_month.merge(df_last_month_per_year, on='year', how='left')

df_last_day_per_year_month = df_last_day_per_year_month[df_last_day_per_year_month['month'] == df_last_day_per_year_month['last_month']]

# don't need 'last_month' column anymore so delete it
del df_last_day_per_year_month['last_month']

# inner merge to filter original df to keep only the dates that are max month, day per year
df = df.merge(df_last_day_per_year_month, on=['year', 'month', 'day'], how='inner')

print(df)
#    year  month  day
# 0  2010     12   28
# 1  2011     11   20


下面是一个oneliner,它将通过按Date分组并将^{}设置为一个月来过滤月份的最后几天,然后从每个组中获取最后一行:

df.loc[df.groupby(pd.Grouper(key='Date', freq='1M')).Date.idxmax()]

正如您在问题开头提到的,您希望查找每年12月的最后一天,您可以按年份分组日期,并按^{}获取组内的最后一个条目,如下所示:

df.groupby(df['Date'].dt.year, as_index=False).last()

如果您还想查找一个月的最后一天(如您在问题末尾所述),可以按年份和月份对日期进行分组,并按^{}获取组中的最后一个条目,如下所示:

df.groupby([df['Date'].dt.year, df['Date'].dt.month], as_index=False).last()

相关问题 更多 >