You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按城市统计事件21与2先后发生次数及代码无限循环排查

按城市统计事件先后发生次数的代码问题排查与解决

需求

按城市统计两类事件的先后发生次数:

  • 事件编号21发生在事件编号2之前的次数
  • 事件编号2发生在事件编号21之前的次数

数据集

import pandas as pd

data = { 
    'city': ['Amsterdam', 'Vienna', 'Paris', 'Paris',  'Istanbul', 'Istanbul','Delhi', 'London', 'London', 'Barcelona', 'Barcelona'], 
    'date': [ '2022-09-01T11:34:53', '2022-09-01T13:37:37', '2022-09-01 10:44:22.000', '2022-09-01T10:39:33', '2022-09-01 16:18:24.000', '2022-09-01T16:15:14', '2022-09-01T13:28:33', '2022-09-01 15:50:54.000', '2022-09-01T15:51:07', '2022-09-01 12:24:26.000','2022-09-01T12:24:07' ], 
    'year': [ '2022']*11,
    'month': [9]*11,
    'hour': [ 11,13,11,10,17,16,13,16,16,13,12 ],
    'eventcode': [ 'J']*11,
    'eventnumber': [ '21', '21', '2', '21', '2', '21', '21', '2', '21', '2','21' ]
}

df = pd.DataFrame(data, columns= ['city', 'date', 'year',  'month', 'hour', 'eventcode','eventnumber' ])

原代码问题

一段代码可正常统计事件21在事件2之前的次数,但调换事件编号后会陷入无限循环:

可正常运行的代码

import numpy as np

bc=np.array(df['city'])
un_bc,bc_index,bc_count=np.unique(bc,return_counts=True,return_index=True)
new_df=pd.DataFrame()
count=0

for i,j in zip(bc_index,bc_count):
    j=j+i-1
    while i+1 <= j:
        if df.iat[i,7]==21 and df.iat[i+1,7]==2:
            count +=1
            new_df=new_df.append(df[i:i+2])
        i +=1
        
print(count)

陷入无限循环的代码

import numpy as np

bc=np.array(df['city'])
un_bc,bc_index,bc_count=np.unique(bc,return_counts=True,return_index=True)
new_df=pd.DataFrame()
count=0

for i,j in zip(bc_index,bc_count):
    j=j+i-1
    while i+1 <= j:
        if df.iat[i,7]==2 and df.iat[i+1,7]==21:
            count +=1
            new_df=new_df.append(df[i:i+2])
        i +=1
        
print(count)

问题排查

  • 列索引错误:eventnumber是DataFrame的第7列(从1计数),但iat使用0-based索引,正确索引应为6而非7。原代码中df.iat[i,7]访问不存在的列,实际会抛出IndexError,推测是笔误。
  • 数据类型不匹配:数据集里eventnumber是字符串类型(如'2'),但代码中用整数2做比较,导致条件永远不成立。
  • 循环变量滥用:在for循环中修改迭代变量i,会破坏for循环的迭代逻辑,处理完一个城市后i的值已被修改,后续循环可能进入异常逻辑,最终导致无限循环。

解决方法

改用Pandas分组功能,按城市分组后先按时间排序,再检查事件先后顺序,代码简洁且无逻辑漏洞:

# 将date列转为datetime类型,确保时间排序准确
df['date'] = pd.to_datetime(df['date'])

# 按城市分组,统计每个城市内事件的先后情况
result = df.groupby('city').apply(lambda x: {
    '2_before_21': ((x.sort_values('date')['eventnumber'].shift() == '2') & (x.sort_values('date')['eventnumber'] == '21')).sum(),
    '21_before_2': ((x.sort_values('date')['eventnumber'].shift() == '21') & (x.sort_values('date')['eventnumber'] == '2')).sum()
}).apply(pd.Series)

# 计算总次数
total_2_before_21 = result['2_before_21'].sum()
total_21_before_2 = result['21_before_2'].sum()

print(f"事件2在事件21之前发生的总次数:{total_2_before_21}")
print(f"事件21在事件2之前发生的总次数:{total_21_before_2}")

代码说明

  1. 先将date转为datetime类型,保证时间排序的准确性。
  2. 按城市分组后,对每个城市的事件按时间排序,用shift()获取前一行的事件编号,比较当前行与前一行的事件组合,统计符合条件的次数。
  3. 最后汇总所有城市的统计结果,得到总次数。

运行结果符合预期:事件2在事件21之前发生1次,事件21在事件2之前发生3次。

内容的提问来源于stack exchange,提问作者Sar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:15:21