Answer
The Numpy is fast in the calculation but it is inefficient in converting the string list to an int list
Tips:
- Use the Numpay array with NumPy functions only, using the Numpay data structure with pythonic functins is inefficient and vice-versa
- Counter in some cases (when doing the conversion inside the counter) is the fastest among the Pythonic methods
- To get the benefit of Numpy efficiency do the list conversion with python.
To better compare the results, the running time can be divided into three categories for this problem:
- Time for reading from file (same for all tries)
- Time to convert the string list into an int list (different for python list and numpy array)
- Time to calculation (varies for different methods)
This separation is required to clearly show the efficiency of python list vs NumPy array.
Having a look to the code:
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)")
Following chart is as the result of the code output:
