有一个包含1000万个数字的列表(PRICE_LIST),其价格范围为(0-100).因此,我想做以下操作:

  1. 使用此条件筛选列表(List_Item<30)
  2. 将每个List_Item与固定数字相乘(映射)
  3. 计算所有元素的总和(减go )

以下是示例代码:

import time
import numpy as np
from functools import reduce

with open('price_list.txt') as f:
    price_list = f.read().split('\n')
    
price_list = np.array(price_list).astype(int)  # convert string to int

我try 了以下选项:

  • 使用数字支付模块(0.1069948673248291秒):total = np.sum(price_list[price_list < 30] * 1.05)

  • 使用暴力循环(9.485718965530396秒)

  • 使用筛选、映射和还原功能(10.078220844268799秒)

  • 使用列表理解(8.609008073806763秒):total= sum([x * 1.05 for x in price_list if x <30])

  • 使用发电机(8.780538320541382秒):total= sum((x * 1.05 for x in price_list if x <30))

显然,NumPy模块在这些操作中速度非常快.有没有其他解决方案可以使用Python内置函数和功能来更快地运行这段代码?

推荐答案

回答

Numpy在计算中速度很快,但在将字符串列表转换为int列表时效率较低

小贴士:

  1. 仅将Numpay数组与NumPy函数一起使用,将Numpay数据 struct 与Pythonic函数一起使用效率很低,反之亦然
  2. 计数器在某些情况下(在计数器内执行转换时)是Pythonic方法中最快的
  3. 要获得Numpy效率的好处,请使用Python进行列表转换.

为了更好地比较结果,该问题的运行时间可以分为三类:

  1. 读取文件的时间(所有try 都相同)
  2. 将字符串列表转换为整型列表的时间(对于pythonlist和numpy数组不同)
  3. 计算时间(因方法不同而异)

为了清楚地显示python list和NumPy数组的效率,这种分离是必需的. 请看一下代码:

import time
import numpy as np
from functools import reduce
from collections import Counter


def print_result(total_price, duration, method):
    print('{method:<35s} {0:>20.3f} (sec), total_price={1:<10.3f}'
          .format(duration, total_price, method=method))


start = time.time()
with open('price_list.txt') as f:
    price_list = f.read().split('\n')
print('Duration for reading from file: {0:<50.3f}'.format(time.time() - start))

start = time.time()
np_price_array = np.array(price_list).astype(int)  # uing numpy array
print('Duration for converting to numpy int array: {0:<50.3f}'.format(
    time.time() - start))

start = time.time()
price_list = list(map(int, price_list))
print('Duration for converting to python int list: {0:<50.3f}'.format(
    time.time() - start))

start = time.time()    
total_price = np.sum(np_price_array[np_price_array < 30] * 1.05)
print_result(total_price, time.time() - start, "NumPy function (numpy array)")

start = time.time()
total_price = sum([x for x in np_price_array if x < 30])*1.05
print_result(total_price, time.time() - start,
             "List comprehension (numpy array)")


start = time.time()
total_price = sum((x for x in price_list if x < 30))*1.05
print_result(total_price, time.time() - start, "List generator (Python list)")

start = time.time()
total_price = sum([x for x in price_list if x < 30])*1.05
print_result(total_price, time.time() - start,
             "List comprehension (Python list)")

start = time.time()
total_price = sum([float(x[0]) * float(x[1])
                  for x in Counter(price_list).items() if x[0] < 30]) * 1.05
print_result(total_price, time.time() - start, "Counter (Python list)")

start = time.time()
total_price = reduce(
    lambda x, y: x+y, filter(lambda x: x < 30, price_list)) * 1.05
print_result(total_price, time.time() - start, "functions (Python list)")

以下图表是代码输出的结果:

enter image description here

Python相关问答推荐

为什么判断pd.DataFrame的值与判断pd.Series的值存在差异(如果索引中有值)?

在有限数量的唯一字母的长字符串中,找到包含重复不超过k次的所有唯一字母的最长子字符串

有没有办法清除气流中的僵尸

Pandas 群内滚动总和

在Python中管理多个OpenGVBO和VAO实例

过载功能是否包含Support Int而不是Support Int?

NumPy中的右矩阵划分,还有比NP.linalg.inv()更好的方法吗?

剧作家Python没有得到回应

在内部列表上滚动窗口

仿制药的类型铸造

当独立的网络调用不应该互相阻塞时,'

为什么抓取的HTML与浏览器判断的元素不同?

我如何根据前一个连续数字改变一串数字?

NumPy中条件嵌套for循环的向量化

递归访问嵌套字典中的元素值

Odoo 16使用NTFS使字段只读

pandas在第1列的id,第2列的标题,第3列的值,第3列的值?

python panda ExcelWriter切换动态公式到数组公式

为什么'if x is None:pass'比'x is None'单独使用更快?

具有相同图例 colored颜色 和标签的堆叠子图