I'm iterating through a list of strings and translating them into arrays of 1's, -1's, and 0's. For example - I may have the following list:
A,B,-C
A,-D
B,C,-D
Which will become a "biglist" equal to:
[
[1 1 -1 0],
[1 0 0 -1],
[0 1 1 -1]
]
At the moment, I'm simply looping through every line of strings, assigning values of 1 or -1 to the string if it is unique, and zeroing out the ones that do not exist (for example, D is not present in the first line, so it is 0). The silly way I'm doing the above is basically:
for line_of_strings in all_strings:
for the_string in line_of_strings:
entry[string_index] = (1 or -1)
biglist.append(entry)
Eventually, I have a nice set of lists on which I run:
scipy.optimize.nnls(biglist)
This works, but winds up taking up a truckload of memory and time. Is there a more efficient way to go about this? Using numpy or scipy arrays/matrices, perhaps?
解决方案
Using numpy arrays instead of lists seems to make quite a bit of difference timewise, at least in a trivial example:
$ python -mtimeit -s"from scipy.optimize import nnls; m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; b=[1, 2, 3]" "nnls(m, b)"
10000 loops, best of 3: 38.5 usec per loop
$ python -mtimeit -s"import numpy as np; from scipy.optimize import nnls; m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); b=[1, 2, 3]" "nnls(m, b)"
100000 loops, best of 3: 20 usec per loop
$ python -mtimeit -s"import numpy as np; from scipy.optimize import nnls; m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); b=np.array([1, 2, 3])" "nnls(m, b)"
100000 loops, best of 3: 11.4 usec per loop
I'd expect that numpy arrays would have smaller memory footprint as well. If your input is reasonably sparse, and if the performance is still not satisfactory, it might be worth investigating if nnls accepts sparse matrices.