【问题标题】:Optimizing list iteration优化列表迭代
【发布时间】:2021-07-25 11:49:15
【问题描述】:

我对编码很陌生,目前正在努力研究如何针对更大的列表优化此代码。

    import pandas as pd
import random
from time import time

rows = []

list1 = [random.randint(1, 100) for i in range(1_000_000)]
list2 = [random.randint(1, 100) for i in range(1_000_000)]
list3 = [random.randint(1, 100) for i in range(1_000_000)]
list4 = [random.randint(1, 100) for i in range(1_000_000)]

start = time()

for i in range(len(list1) - 1):
    if list1[i] < list2[i] and list1[i + 1] > list2[i + 1]:
        dict1 = {1: list1[i], 2: '+'}
        rows.append(dict1)
    elif list1[i] > list2[i] and list1[i + 1] < list2[i + 1]:
        dict1 = {1: list1[i], 2: '-'}
        rows.append(dict1)

    if list3[i] < list4[i] and list3[i + 1] > list4[i + 1]:
        dict1 = {1: list3[i], 2: '+'}
        rows.append(dict1)
    elif list3[i] > list4[i] and list3[i + 1] < list4[i + 1]:
        dict1 = {1: list3[i], 2: '-'}
        rows.append(dict1)
    else:
        dict1 = {1: list3[i], 2: '#'}
        rows.append(dict1)
end = time()
print(end - start)
df = pd.DataFrame(rows)

10_000_000 个条目大约需要 30 秒。它线性增长。 有没有办法针对更大的数字对其进行优化?

我觉得 for 循环和 if-else 语句是最耗时的语句,但我想不出优化它们的方法。

【问题讨论】:

  • 它不会呈指数级增长,而是会呈线性增长。是 O(N)。你到底想在这里完成什么?
  • 顺便说一句,您的第一个语句有错字:最后一个 list1 应该是 list2。这里的整个概念是有缺陷的。如果list1[i] &lt; list2[i],则按定义list1[i]+1 &lt; list2[i] + 1。我不认为这是你打算做的。
  • 您在寻找这两个系列的交叉点吗?我假设您的意思是if list1[i] &lt; list2[i] and list1[i+1] &gt; list2[i+1]。如果是这样,这样做的方法是使用numpy,将两个列表相减,然后查找与np.where(np.diff(np.sign(x))) 的零交叉。
  • 对于错误,我很抱歉,我现在修正了错别字。
  • 好的,谢谢,我试试看。

标签: python-3.x list for-loop optimization large-data


【解决方案1】:

感谢@Tim Roberts 和this question,我找到了优化代码的方法。

from time import time

list1 = np.array([random.randint(1, 100) for i in range(10_000_000)])
list2 = np.array([random.randint(1, 100) for i in range(10_000_000)])
list3 = np.array([random.randint(1, 100) for i in range(10_000_000)])
list4 = np.array([random.randint(1, 100) for i in range(10_000_000)])

start = time()
list_sub1 = np.subtract(list2, list1)
list_sub2 = np.subtract(list4, list3)
positive = list_sub1 > 0
positive2 = list_sub2 > 0
results = np.bitwise_xor(positive[1:], positive[:-1]).nonzero()[0]
results2 = np.bitwise_xor(positive2[1:], positive2[:-1]).nonzero()[0]
end = time()
print(end-start)

这样分析 10_000_000 个条目只需要 0.25 秒,而不是 30 秒。

我将@Tim Roberts 建议的np.where(np.diff(np.sign(x)))更改为np.bitwise_xor(positive[1:], positive[:-1]).nonzero()[0] 因为这让我的时间增加了 x2。

注意:该程序确实将 0 视为负数,并且仅记录 >0 (1/-1) 的更改。使用 np.sign() 0 被正确处理(1/0/-1)。就我而言,我不需要任何进一步的区分,所以我选择了更快的方法。

The Numpy Doc 如果您不熟悉矢量化和整体 numpy,那就太好了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-14
    • 2013-05-29
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多