【问题标题】:How to make organisation function more efficient如何让组织功能更高效
【发布时间】:2019-07-31 10:08:01
【问题描述】:

首先,这不是一个高优先级的问题,因为一切正常且运行良好,但是我无法摆脱这样的感觉,即如果我没有遇到严重的脑阻塞,代码可以更有效地运行.

这里是要点:我正在从 python 运行查询以从数据库中获取一堆条目。接下来我需要遍历条目,找到某个元素的最小值,最大值,然后确定这两个值之间的1/4、1/2和3/4处的值。最后,我需要计算有多少条目适合这些类别。

results = ({
   'min':999999,
   'min-value':0,
   'quarter':0,
   'quarter-value':0,
   'mid':0,
   'mid-value':0,
   'three-quarter':0,
   'max-value':0,
   'max':0
})

for query_value in q:
   results['min'] = min(query_value, results['min'])
   results['max'] = max(query_value, results['max'])

results['mid'] = (results['min']+results['max'])/2
results['quarter'] = (results['min']+results['mid'])/2
results['three-quarter'] = (results['mid']+results['max'])/2

for query_value in q:
   if query_value < results['quarter']:
      results['min-value'] += 1
   elif query_value < results['mid']:
      results['quarter-value'] += 1
   elif query_value < results['three-quarter']:
      results['mid-value'] += 1
   else:
      results['max-value'] += 1

return results

如您所见,我必须循环两次值,这对我来说是一个主要的危险信号。我将继续自己努力。我曾想过对数据库运行第二个 sql 查询,分别请求最大值和最小值,但 sql 在这方面会比 python 更有效吗?我只是想降低运行时间。

任何建议表示赞赏。

编辑:我想指出,这绝对是相关代码的最小表示。显然,正确的代码包括测试以确保元素不为空,并且确实必须对获取的值进行更多处理,但这是问题的核心。

【问题讨论】:

  • 如果它工作(非常重要的要求),这可能应该继续the Code Review SE
  • 看起来不错。这是O(n) 复杂性。无法避免对集合进行第二次迭代
  • q 是什么类型?你可以使用例如NumPy?
  • @Renat O(n) 很好,但 O(n) 的常数越小越好 ;-)
  • 我认为你应该考虑在数据库级别进行

标签: python performance loops


【解决方案1】:

我了解到q 可以迭代,其结果本质上是一个数字。 如果q 的长度很大,您最好使用以下方法:

import numpy as np

results = {}

hist, edges = np.histogram(q, 4)  # possibly: `q.all()` instead of `q`
results['min-value'], results['quarter-value'], results['mid-value'], results['max-value'] = hist
results['min'], results['quarter'], results['mid'], results['three-quarter'], results['max'] = edges

此外,您可能需要考虑为数组的键使用更多信息名称。例如,min-value 会误导我。

我宁愿使用,例如:

results['bin_1/4'], ... = hist
results['min'], results['1/4-val'], results['mid-val'], results['3/4-val'], results['max'] = edges

除了更明确之外,还可以很容易地自动化,例如如果 n_bins 值发生变化,因此更容易扩展:

n_bins= 4
results.update({f'bin{i}/{n_bins}': x for i, x in enumerate(hist)})

只是为了让您了解这些数字,请查看这些基准,这些基准显示所提议方法的速度提高了约 100 倍(蓝色是您的版本,橙色是我的;第二行是对最快解决方案的放大):

【讨论】:

  • 这太棒了。我在开场消息中输入的版本是 live atm,但我会玩这个,看看我是否可以在下一个版本更新中使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
相关资源
最近更新 更多