【问题标题】:How to iterate through a "window" of data in a dataset?如何遍历数据集中的数据“窗口”?
【发布时间】:2013-07-31 03:23:06
【问题描述】:

我在 mysql 中有一个 150 行的数据集。我有一组 2 个循环,它们根据一些用户输入和数据集运行数学计算。该代码对 30 行窗口进行计算,并将每个 30 行窗口的结果累加到一个数组中。我的意思是,我对第 0-29 行、然后是 1-30、然后是 2-31 等进行“循环”计算......这将导致 120 个“循环”。

现在 for 循环是这样设置的(还有更多字段,为了这个问题的简单性,我只是修剪了代码。

    $period=30;
    $query = "SELECT * FROM table"; 
    $result = mysql_query($query); 
    while ($row = mysql_fetch_assoc($result)){ 
        $data[] = array("Date" => $row['Date'], "ID" => $row['ID']); 
    }
    for($i=0;$i<(count($data)-$window);$i++){
        for($j=0;$j<$window;$j++){
            //do calculations here with $data[]
            $results[$i][$j]= calculations;
        }
    }

这适用于我拥有的行数。但是,我将脚本打开到具有不同窗口(360 行)的更大数据集(1700 行)。这意味着迭代次数呈指数增长。它给了我一个内存不足的错误。快速使用 memory_get_peak_usage() 表明内存会不断增加。

我开始认为让循环搜索该数据数组非常费力,尤其是当“窗口”与许多“循环”重叠时。示例:循环 0 遍历第 0-29 行。循环 1 遍历第 1-30 行。所以,这两个周期共享他们需要的一行数据,但我告诉 PHP 每次都寻找新数据。

有没有办法更好地构建它?对于运行这些并发周期,我有点迷失了。

【问题讨论】:

  • 答案取决于您在遗漏的代码中所做的事情。如果你能更好地描述你实际在做什么,你会得到更好的帮助。
  • 我只是在使用用户输入 ($_POST) 和数据集进行基本数学运算。

标签: php mysql loops


【解决方案1】:

我认为正在消耗内存的数组将是$result 数组。在您的小样本中,它将是一个包含 150x149 个单元的二维数组。 array( 150, 149 )。每个元素 144 字节,即 3,218,400 字节,略高于 3 Meg + 剩余存储桶空间。

在您的第二个较大样本中,它将是 array(1700,1699)。每个元素 144 字节,即 415,915,200 字节,略高于 406Meg + 剩余存储桶空间,仅用于保存计算结果。

我认为您需要询问您是否真的需要保存所有这些数据。如果你真的这样做了,你可能不得不想出另一种存储方式。

我认为尝试 1000 次奇数的数据库调用没有任何意义,因为这只会增加开销,因为您仍然必须在数组中维护庞大的结果列表。

【讨论】:

  • 呵呵,我从没想过要计算数组大小。启蒙。也许对于更大的数据集,做一个用户可以稍后返回的后台进程并将信息存储在数据库中几个小时更有意义。这还不包括我认为我真正的数组结构很愚蠢的事实,因为我定义了奇怪的数组并且只是继续运行它。它类似于 $results[0][0][$i][$j]... 这可能会以指数方式使其更大。哇!
【解决方案2】:

SQL 方式

您可以使用LIMIT 来完成此操作

$period = 30;
$cycle = 0; //
$query = "SELECT * FROM table LIMIT $cycle,$period";

这将只返回每个周期所需的结果。您将需要循环和递增$cycle。不过,您现在的做法可能会更好。

这不会循环返回并获取第一个数据,您必须添加额外的逻辑来处理这种情况。

【讨论】:

  • 那么,您认为进行 120 次数据库调用,而不是进行 1 次数据库调用并将其放入一个数组并在该数组中搜索 120 次更好吗?我问,因为如果我们将此示例外推到更大的数据集(1700 行),最终会产生 1300 次左右的 DB 调用。
  • 不,这可能不是更好。但是,当您进行这些调用时,结果将被缓存。
猜你喜欢
  • 2012-06-05
  • 2010-10-22
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-17
相关资源
最近更新 更多