Python 任何加速暴力的替代方案';理货';算法?

Python 任何加速暴力的替代方案';理货';算法?,python,algorithm,performance,machine-learning,counting,Python,Algorithm,Performance,Machine Learning,Counting,如果这是发布此问题的错误位置,请提前道歉。如果有更好的stack exchange站点,请告诉我 因此,目前正在开发一种犯罪预测算法,该算法基本上在一个城市上铺设一个网格,并预测在未来30天内每个网格入口是否会成为热点(至少发生一次袭击犯罪) 我使用的是纳什维尔市,目前有3446个网格覆盖。我有一个网格数据集,其中包含显示网格所需的所有数据、每个网格的地图坐标以及周围的相邻网格(底部的相邻网格、右侧的相邻网格等等) 以下是预测结果的示例: 在这种情况下,绿色表示正确的预测。红色表示机器学习算

如果这是发布此问题的错误位置,请提前道歉。如果有更好的stack exchange站点,请告诉我

因此,目前正在开发一种犯罪预测算法,该算法基本上在一个城市上铺设一个网格,并预测在未来30天内每个网格入口是否会成为热点(至少发生一次袭击犯罪)

我使用的是纳什维尔市,目前有3446个网格覆盖。我有一个网格数据集,其中包含显示网格所需的所有数据、每个网格的地图坐标以及周围的相邻网格(底部的相邻网格、右侧的相邻网格等等)

以下是预测结果的示例:

在这种情况下,绿色表示正确的预测。红色表示机器学习算法的假阴性,紫色表示假阳性

为了训练我的神经网络,我使用了如下特征集:

这里的热点是目标值(1和0)。周、月、年是从去年(上周、上月和去年发生的犯罪)中提取的犯罪事件的犯罪记录。我的问题是创建这些功能集需要大量的时间(脚本需要6个多小时)


现在,这段代码在每个网格中循环(总共3446次),在每个网格中循环每个犯罪(大约18000次),计算计数并将其添加到熊猫数据框中…3446*18000是创建此数据集的大约6200万次计算。我觉得这不会花太长时间,但比理想情况下要长得多

有没有关于如何有效加速的想法?在过去的三年中,我每个月都需要运行这个算法,所以每次运行超过5个小时36次对于我的时间限制来说太长了

提前感谢您提供的任何见解

编辑:澄清“网格行”是我在上面列中发布的网格CSV文件中的每条记录(每个网格和相邻网格的位置),“犯罪行”是去年发生的每个犯罪事件:
你做事的方式可以简化为

forall grid
  forall crimes
    if crime.cell == grid.cell
      do something
这种复杂性是
O(|网格|*|犯罪|)

如果你有3k的犯罪和5k的网格,这使得它是15e6次迭代

更好的方法是迭代犯罪并将其中任何一个推送到关联的网格,将所有具有相同网格索引的犯罪叠加到。。。同一炮位

gridIdxToCrimes = {} // to a grid_index you associate all the crimes

for crime_row in crime.iterrows():
  grid_index = crime_row['grid']
  if grid_index not in gridIdxToCrimes:
    gridIdxToCrimes[grid_index] = []
  gridIdxToCrimes[grid_index].push(crime_row)

forall grid_index, grid_row in grid.iterrows():
  topIndex = grid_row['top ']
  if topIndex in gridIdxToCrimes:
    # you get all the crimes above your current grid
    near += count(gridIdxToCrimes[topIndex])


这样你做了O(| crimes |+| grid |)=5k迭代

你做事情的方式可以简化为

forall grid
  forall crimes
    if crime.cell == grid.cell
      do something
这种复杂性是
O(|网格|*|犯罪|)

如果你有3k的犯罪和5k的网格,这使得它是15e6次迭代

更好的方法是迭代犯罪并将其中任何一个推送到关联的网格,将所有具有相同网格索引的犯罪叠加到。。。同一炮位

gridIdxToCrimes = {} // to a grid_index you associate all the crimes

for crime_row in crime.iterrows():
  grid_index = crime_row['grid']
  if grid_index not in gridIdxToCrimes:
    gridIdxToCrimes[grid_index] = []
  gridIdxToCrimes[grid_index].push(crime_row)

forall grid_index, grid_row in grid.iterrows():
  topIndex = grid_row['top ']
  if topIndex in gridIdxToCrimes:
    # you get all the crimes above your current grid
    near += count(gridIdxToCrimes[topIndex])


通过这种方式,您完成了O(| crimes |+| grid |)=5k次迭代

似乎对于每个网格,您迭代了每个crimes |行。。。您应该描述什么是犯罪行及其与网格行的关系(例如,为什么它们是相等的?它们是某个对象??)。您还应该考虑给出一个非常小的数据集,如果语句(从GRIDYROWOR[PUT],BASEL,……,[ButtoMultLe])被链接为IF其他构造,那么这些复制脚本可以分开吗?我想这样做不会影响你的要求。对于countMonth、countWeek和countYear,将条件grid_行['id']==crime_行['grid']作为第一个检查,因为它更具限制性。或者,它可以是网格行['id']==犯罪行['grid']的高级“如果”语句检查,然后是countMonth、countWeek和countYear的三个内部IF语句检查。希望它能对性能有所帮助。@user753642是的,我在地图上的每个网格上迭代,并且针对每个网格,我统计了该特定网格在上周、上月和去年发生的犯罪数量。“犯罪”是指去年在纳什维尔市发生的每一个单独的犯罪事件。我在上面添加了一个犯罪记录的样本。我想我误解了,所以请纠正我:每个犯罪都有一个“网格编号”,那么为什么你要在每个网格单元中查找每个犯罪?扫描犯罪列表,为每个犯罪获取网格编号,更新你想要保留的计数器,转到下一个犯罪,“……在每个网格内它循环遍历每个犯罪(大约18000)”我不明白。是否有18k类型的犯罪,并且您正在计算每个网格中这些犯罪发生的频率,或者这些18k中的每一个都对应于一个实际的犯罪实例?在这种情况下,犯罪可以发生在多个网格单元中吗?你能不能只创建一个map
{crime\u id:grid\u id}
而不是一个CRIMExGRID表?似乎对于每个网格,你都会迭代每个crime\u行。。。您应该描述什么是犯罪行及其与网格行的关系(例如,为什么它们是相等的?它们是某个对象??)。您还应该考虑给出一个非常小的数据集,如果语句(从GRIDYROWOR[PUT],BASEL,……,[ButtoMultLe])被链接为IF其他构造,那么这些复制脚本可以分开吗?我想这样做不会影响你的要求。对于countMonth、countWeek和countYear,将条件grid_行['id']==crime_行['grid']作为第一个检查,因为它更具限制性。或者,它可以是网格行['id']==犯罪行['grid']的高级“如果”语句检查,然后是countMonth、countWeek和countYear的三个内部IF语句检查。希望它能对性能有所帮助。@user753642是的,我在地图上的每个网格上迭代,并且针对每个网格,我统计了该特定网格在上周、上月和去年发生的犯罪数量。“犯罪”是指去年在纳什维尔市发生的每一个单独的犯罪事件。我添加了一个c