统计各时段演出最大连续售票数的Python代码问题求助
问题分析与解决方案
原代码的核心问题
- 循环终止条件
i < len(df)-1跳过了最后一行数据,导致最后一个小时(10点)的统计无法输出 - 仅在小时切换时输出结果,循环结束后未处理最后一个小时的剩余统计数据
- 未跟踪最大连续售票数:当前代码只累加连续次数,但同一小时内可能存在多段连续序列,需要取最长的那段值
- 计数逻辑偏差:连续n条相同记录的实际连续售票数是n,但原代码的累加值是n-1,且未考虑单段连续结束后需重置当前计数并更新最大值
修复后的循环版本
如果坚持用循环实现,可按以下方式修改:
# 初始化变量 i = 0 current_adel = 0 current_kanye = 0 max_adel = {} max_kanye = {} prev_hour = df["purchase_hour"].iloc[0] prev_ticket = df["ticket_desc"].iloc[0] # 初始化当前小时的计数 if prev_ticket == "Adel L.A. Concert": current_adel = 1 else: current_kanye = 1 while i < len(df): # 处理到最后一行,或者当前行与下一行小时/演出不同的情况 if i == len(df)-1 or (df["purchase_hour"].iloc[i] != df["purchase_hour"].iloc[i+1] or df["ticket_desc"].iloc[i] != df["ticket_desc"].iloc[i+1]): # 更新当前小时的最大值 hour = df["purchase_hour"].iloc[i] if prev_ticket == "Adel L.A. Concert": if hour not in max_adel or current_adel > max_adel[hour]: max_adel[hour] = current_adel current_adel = 0 else: if hour not in max_kanye or current_kanye > max_kanye[hour]: max_kanye[hour] = current_kanye current_kanye = 0 # 准备下一段的初始计数 if i != len(df)-1: next_ticket = df["ticket_desc"].iloc[i+1] if next_ticket == "Adel L.A. Concert": current_adel = 1 else: current_kanye = 1 prev_ticket = next_ticket else: # 连续相同演出,累加当前计数 if df["ticket_desc"].iloc[i] == "Adel L.A. Concert": current_adel += 1 else: current_kanye += 1 i += 1 # 输出结果 for hour in sorted(max_adel.keys() | max_kanye.keys()): print(f"adel ticket at {hour} is {max_adel.get(hour, 0)}") print(f"kanye ticket at {hour} is {max_kanye.get(hour, 0)}")
更高效的Pandas向量化解法
用Pandas内置方法处理连续序列,效率更高,适合大数据量:
import pandas as pd # 1. 标记连续相同演出的分组 df['is_same'] = (df['purchase_hour'] == df['purchase_hour'].shift()) & (df['ticket_desc'] == df['ticket_desc'].shift()) df['group_id'] = (~df['is_same']).cumsum() # 2. 按小时、演出、分组统计每组的连续售票数 grouped = df.groupby(['purchase_hour', 'ticket_desc', 'group_id']).size().reset_index(name='continuous_count') # 3. 按小时和演出取最大连续数 result = grouped.groupby(['purchase_hour', 'ticket_desc'])['continuous_count'].max().unstack(fill_value=0) # 4. 格式化输出 for hour in result.index: print(f"adel ticket at {hour} is {result.loc[hour, 'Adel L.A. Concert']}") print(f"kanye ticket at {hour} is {result.loc[hour, 'Kanye West Concert']}")
代码说明
- 第一步通过
shift()对比当前行与上一行的小时和演出,标记是否连续;再用cumsum()生成连续组的ID - 第二步按小时、演出、组ID分组,统计每组的长度(即连续售票数)
- 第三步按小时和演出取每组的最大值,得到每个小时每场演出的最大连续售票数
- 最后格式化输出结果,完全符合需求
内容的提问来源于stack exchange,提问作者Alon
相关产品推荐
相关产品推荐

