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

如何高效筛选纽约市犯罪数据集并按月分组统计绘制时序图

优化500万+条犯罪数据集的按月统计与绘图流程

问题核心

你的原始代码反复筛选、分组500万条数据,导致计算耗时极高。已经写出的isin一次性筛选是正确的优化方向,接下来只需通过一次分组统计就能得到所有犯罪类型的月度数据,完美适配原有绘图代码。

优化后的完整处理代码

import pandas as pd

# 1. 定义目标犯罪类型
crime_select = ["DANGEROUS DRUGS", "ASSAULT 3 & RELATED OFFENSES", "PETIT LARCENY", "FELONY ASSAULT", "DANGEROUS WEAPONS"]

# 2. 一次性筛选目标数据(只遍历数据集1次)
filtered_crime = df[df["OFNS_DESC"].isin(crime_select)]

# 3. 转换日期为年月格式
filtered_crime['ARREST_YM'] = filtered_crime["ARREST_DATE"].dt.to_period('M')

# 4. 一次分组完成所有统计(按年月+犯罪类型分组,统计数量)
crime_monthly = filtered_crime.groupby(['ARREST_YM', 'OFNS_DESC']).size().unstack(fill_value=0)

代码详细解释

  • 一次性筛选:isin替代多次==判断,只遍历数据集1次,直接过滤出所有目标犯罪类型,比原代码少遍历4次500万条数据,大幅节省时间。
  • 日期转换:给筛选后的数据集新增ARREST_YM列,存储年月周期格式(如2020-01),方便后续分组。
  • 分组统计:
    • groupby(['ARREST_YM', 'OFNS_DESC']):同时按「年月」和「犯罪类型」分组,把每个月的每种犯罪单独成组。
    • size():统计每组的记录数(即该月该类犯罪的次数)。
    • unstack(fill_value=0):把犯罪类型从行索引转成列,最终得到的crime_monthly是一个DataFrame:
      • 行索引是年月(和原代码的arrest_ym一致)
      • 列是5种犯罪类型,每个单元格对应该月该类犯罪的次数,缺失月份自动补0。

适配原有绘图代码

原绘图代码可以直接复用,只需把单独的变量替换成crime_monthly的列即可,也可以改成循环方式更简洁:

方式1:适配原有逐行绘图逻辑

import matplotlib.pyplot as plt

plt.figure(figsize = (20, 10))
# 直接从crime_monthly取列数据,和原变量结构完全一致
plt.plot(crime_monthly.index.astype(str), crime_monthly["DANGEROUS DRUGS"], 'b-', label = "Dangerous Drugs")
plt.plot(crime_monthly.index.astype(str), crime_monthly["ASSAULT 3 & RELATED OFFENSES"], 'g-', label = "Assault 3 & Related Offenses")
plt.plot(crime_monthly.index.astype(str), crime_monthly["PETIT LARCENY"], 'r-', label = "Petit Larceny")
plt.plot(crime_monthly.index.astype(str), crime_monthly["FELONY ASSAULT"], 'c-', label = "Felony Assault")
plt.plot(crime_monthly.index.astype(str), crime_monthly["DANGEROUS WEAPONS"], 'm-', label = "Dangerous Weapons")

# 保留原有的坐标轴设置
x_labels = crime_monthly.index.astype(str)
plt.xticks(x_labels[::6], rotation=45)
plt.xlabel("Month")
plt.ylabel("Crime Count")
plt.title("Monthly Crime Frequency")
plt.legend(loc = "best")
plt.show()

方式2:循环绘图更简洁(推荐)

如果后续要调整犯罪类型,只需修改crime_select列表,不需要改绘图代码:

import matplotlib.pyplot as plt

# 定义颜色映射,对应5种犯罪类型
color_map = {
    "DANGEROUS DRUGS": 'b-',
    "ASSAULT 3 & RELATED OFFENSES": 'g-',
    "PETIT LARCENY": 'r-',
    "FELONY ASSAULT": 'c-',
    "DANGEROUS WEAPONS": 'm-'
}

plt.figure(figsize = (20, 10))
# 循环遍历每个犯罪类型列,自动绘图
for crime_type in crime_select:
    plt.plot(crime_monthly.index.astype(str), crime_monthly[crime_type], color_map[crime_type], label = crime_type.replace('_', ' ').title())

x_labels = crime_monthly.index.astype(str)
plt.xticks(x_labels[::6], rotation=45)
plt.xlabel("Month")
plt.ylabel("Crime Count")
plt.title("Monthly Crime Frequency")
plt.legend(loc = "best")
plt.show()

优化效果对比

  • 原代码:遍历数据集5次(筛选)+ 5次分组统计,总计10次大遍历。
  • 优化后:遍历数据集1次(筛选)+ 1次分组统计,总计2次大遍历。
    对于500万条数据,计算速度至少提升4-5倍,内存占用也会大幅降低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:44:59