筛选含重复日期的DataFrame行并按日期分组堆叠展示
解决DataFrame筛选重复日期行并分组显示的问题
原始数据
Date Name Grade Hobby 01/01/2005 Albert 4 Drawing 08/04/1996 Martha 6 Horseback riding 03/03/2003 Jack 5 Singing 07/01/2001 Millie 5 Netflix 24/09/2000 Julie 7 Sleeping ...
需求
筛选出仅包含重复日期的行(即日期出现次数≥2的行),然后按时间先后顺序分组,最终展示为相同日期仅在第一行显示、后续同日期行的日期列留空的格式。
你尝试过的代码
代码1
same=df['Date'].value_counts() same=same.loc[lambda x:x >=2] mult=same.index.to_list() for i in df['Date']: if i not in mult: df.drop(df[df['Date'==i]].index)
代码2
new=df.loc[df['Date'].isin(mult)] plot=pd.pivot_table(new, index=['Date'],columns=['Name'])
问题分析
- 代码1的问题:循环中直接
drop不会修改原DataFrame(需加inplace=True),且df['Date'==i]是语法错误(应为df['Date'] == i),同时循环遍历行效率极低,完全没必要。 - 代码2的问题:
pivot_table是做数据透视的工具,会把Name转为列,仅保留每个日期的聚合结果,不符合保留所有行的需求。
正确解决方案
步骤1:筛选重复日期的行
先找出出现次数≥2的日期,再筛选对应行:
# 统计每个日期的出现次数 date_counts = df['Date'].value_counts() # 筛选出现次数≥2的日期 repeat_dates = date_counts[date_counts >= 2].index # 过滤数据 filtered_df = df[df['Date'].isin(repeat_dates)].copy()
步骤2:按时间排序
先将Date列转为日期格式,再按时间排序:
# 转换日期格式(你的日期是日/月/年,需加dayfirst=True) filtered_df['Date'] = pd.to_datetime(filtered_df['Date'], dayfirst=True) # 按日期排序 filtered_df = filtered_df.sort_values('Date') # 转回原字符串格式(保持显示一致) filtered_df['Date'] = filtered_df['Date'].dt.strftime('%d/%m/%Y')
步骤3:设置分组显示格式
让相同日期仅在第一行显示,后续行留空:
# 标记每个日期的第一行,其余行日期设为空字符串 filtered_df['Date'] = filtered_df.groupby('Date')['Date'].transform(lambda x: [x.iloc[0]] + ['']*(len(x)-1)) # 重置索引(可选,让索引连续) filtered_df = filtered_df.reset_index(drop=True)
完整代码
import pandas as pd # 假设你的原始DataFrame为df # 步骤1:筛选重复日期的行 date_counts = df['Date'].value_counts() repeat_dates = date_counts[date_counts >= 2].index filtered_df = df[df['Date'].isin(repeat_dates)].copy() # 步骤2:按时间排序 filtered_df['Date'] = pd.to_datetime(filtered_df['Date'], dayfirst=True) filtered_df = filtered_df.sort_values('Date') filtered_df['Date'] = filtered_df['Date'].dt.strftime('%d/%m/%Y') # 步骤3:设置分组显示格式 filtered_df['Date'] = filtered_df.groupby('Date')['Date'].transform(lambda x: [x.iloc[0]] + ['']*(len(x)-1)) filtered_df = filtered_df.reset_index(drop=True) print(filtered_df)
运行后即可得到目标格式:
Date Name Grade Hobby 08/08/1996 Martha 6 Horseback riding Matt 4 Sleeping Paul 5 Cooking 24/09/2000 Julie 7 Sleeping Simone 4 Sleeping ...
内容的提问来源于stack exchange,提问作者Mary
相关产品推荐
相关产品推荐

