Re: Efficient way to sum a product of numbers...
After simplifying my problem, I can say that I want to get the sum of the product of two culumns: Say m= [[ 'a', 1], [ 'b', 2],[ 'a', 3]] assuming you meant ['c', 3] here...^ r={'a':4, 'b':5, 'c':6} What I need is the calculation 1*4 + 2*5 + 3*4 = 4 + 10 + 12 = 26 and you mean 3*6 here instead of 3*4, which is 18 instead of 12, making the whole sum 4+10+18=32 Then it sounds like you could do something like result = sum(v * r[k] for k,v in m) where m is any arbitrary iterable of tuples. If the keys (the letters) aren't guaranteed to be in r, then you can use defaults (in this case 0, but could just as likely be 1 depending on your intent): result = sum(v * r.get(k,0) for k,v in m) If the conditions above don't hold, you'll have to introduce me to your new math. ;-) -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: Efficient way to sum a product of numbers...
On Aug 31, 6:30 pm, Tim Chase python.l...@tim.thechases.com wrote: After simplifying my problem, I can say that I want to get the sum of the product of two culumns: Say m= [[ 'a', 1], [ 'b', 2],[ 'a', 3]] assuming you meant ['c', 3] here... ^ r={'a':4, 'b':5, 'c':6} What I need is the calculation 1*4 + 2*5 + 3*4 = 4 + 10 + 12 = 26 and you mean 3*6 here instead of 3*4, which is 18 instead of 12, making the whole sum 4+10+18=32 Then it sounds like you could do something like result = sum(v * r[k] for k,v in m) where m is any arbitrary iterable of tuples. If the keys (the letters) aren't guaranteed to be in r, then you can use defaults (in this case 0, but could just as likely be 1 depending on your intent): result = sum(v * r.get(k,0) for k,v in m) If the conditions above don't hold, you'll have to introduce me to your new math. ;-) -tkc Hello Tim, There is no mistake in my original post, so I really meant [ 'a', 3] Imagine that m contains time sheets of suppliers supplier 'a' has worked for you 1 hour supplier 'b' has worked for you 2 hour supplier 'a' has worked for you 3 hour Now supplier 'a' charges $4 per hour supplier 'b' charges $5 per hour supplier 'c' charges $6 per hour I want to know how much I will be charged this month by my pannel of suppliers. 1*4 + 2*5 + 3*4 = 4 + 10 + 12 = 26 This is what I am after. I expect all my suppliers to have handed me in advance the per hour fee. If at least one hasn't, I must know that the result is undefined. Hope this helps Vicente Soler -- http://mail.python.org/mailman/listinfo/python-list
Re: Efficient way to sum a product of numbers...
vsoler wrote: On Aug 31, 6:30 pm, Tim Chase python.l...@tim.thechases.com wrote: After simplifying my problem, I can say that I want to get the sum of the product of two culumns: Say m= [[ 'a', 1], [ 'b', 2],[ 'a', 3]] assuming you meant ['c', 3] here...^ r={'a':4, 'b':5, 'c':6} What I need is the calculation 1*4 + 2*5 + 3*4 = 4 + 10 + 12 = 26 and you mean 3*6 here instead of 3*4, which is 18 instead of 12, making the whole sum 4+10+18=32 Then it sounds like you could do something like result = sum(v * r[k] for k,v in m) where m is any arbitrary iterable of tuples. If the keys (the letters) aren't guaranteed to be in r, then you can use defaults (in this case 0, but could just as likely be 1 depending on your intent): result = sum(v * r.get(k,0) for k,v in m) If the conditions above don't hold, you'll have to introduce me to your new math. ;-) There is no mistake in my original post, so I really meant [ 'a', 3] Ah...that makes more sense of the data. My answer still holds then. Use the r[k] version instead of the r.get(...) version, and it will throw an exception if the rate doesn't exist in your mapping. (a KeyError if you want to catch it) -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: Efficient way to sum a product of numbers...
vsoler vicente.so...@gmail.com writes: m= [[ 'a', 1], [ 'b', 2],[ 'a', 3]] r={'a':4, 'b':5, 'c':6} What I need is the calculation 1*4 + 2*5 + 3*4 = 4 + 10 + 12 = 26 sum(r[k]*w for k,w in m) -- http://mail.python.org/mailman/listinfo/python-list
Re: Efficient way to sum a product of numbers...
On Aug 31, 6:59 pm, Tim Chase python.l...@tim.thechases.com wrote: vsoler wrote: On Aug 31, 6:30 pm, Tim Chase python.l...@tim.thechases.com wrote: After simplifying my problem, I can say that I want to get the sum of the product of two culumns: Say m= [[ 'a', 1], [ 'b', 2],[ 'a', 3]] assuming you meant ['c', 3] here... ^ r={'a':4, 'b':5, 'c':6} What I need is the calculation 1*4 + 2*5 + 3*4 = 4 + 10 + 12 = 26 and you mean 3*6 here instead of 3*4, which is 18 instead of 12, making the whole sum 4+10+18=32 Then it sounds like you could do something like result = sum(v * r[k] for k,v in m) where m is any arbitrary iterable of tuples. If the keys (the letters) aren't guaranteed to be in r, then you can use defaults (in this case 0, but could just as likely be 1 depending on your intent): result = sum(v * r.get(k,0) for k,v in m) If the conditions above don't hold, you'll have to introduce me to your new math. ;-) There is no mistake in my original post, so I really meant [ 'a', 3] Ah...that makes more sense of the data. My answer still holds then. Use the r[k] version instead of the r.get(...) version, and it will throw an exception if the rate doesn't exist in your mapping. (a KeyError if you want to catch it) -tkc It works!!! Thank you -- http://mail.python.org/mailman/listinfo/python-list
Re: Efficient way to sum a product of numbers...
31-08-2009 o 18:19:28 vsoler vicente.so...@gmail.com wrote: Say m= [[ 'a', 1], [ 'b', 2],[ 'a', 3]] r={'a':4, 'b':5, 'c':6} What I need is the calculation 1*4 + 2*5 + 3*4 = 4 + 10 + 12 = 26 That is, for each row list in variable 'm' look for its first element in variable 'r' and multiply the value found by the second element in row 'm'. After that, sum all the products. What's an efficient way to do it? I have thousands of these calculations to make on a big data file. 31-08-2009 o 18:30:27 Tim Chase python.l...@tim.thechases.com wrote: result = sum(v * r[k] for k,v in m) You can also check if this isn't more efficient: from itertools import starmap from operator import mul result = sum(starmap(mul, ((r[name], hour) for name, hour in m))) Or, if you had m in form of two lists: names = ['a', 'b', 'a'] hours = [1, 2, 3] ...then you could do: from itertools import imap as map # - remove if you use Py3.x from operator import mul result = sum(map(mul, map(r.__getitem__, names), hours)) Cheers, *j PS. I've done a quick test on my computer (Pentium 4, 2.4Ghz, Linux): setup = from itertools import starmap, imap ; from operator import mul; import random, string; names = [rndom.choice(string.ascii_letters) for x in xrange(1)]; hours = [random.randint(1, 12) for x in xrange(1000)]; m = zip(names, hours); workers = set(names); r = dict(zip(workers, (random.randint(1, 10) for x in xrange(en(workers) tests = ( ... 'sum(v * r[k] for k,v in m)', ... 'sum(starmap(mul, ((r[name], hour) for name, hour in m)))', ... 'sum(imap(mul, imap(r.__getitem__, names), hours))', ... ) for t in tests: ... print t ... timeit.repeat(t, setup, number=1000) ... print ... sum(v * r[k] for k,v in m) [6.2493009567260742, 6.1892399787902832, 6.2634339332580566] sum(starmap(mul, ((r[name], hour) for name, hour in m))) [9.3293819427490234, 10.280816078186035, 9.2766909599304199] sum(imap(mul, imap(r.__getitem__, names), hours)) [5.7341709136962891, 5.5898380279541016, 5.7318859100341797] -- Jan Kaliszewski (zuo) z...@chopin.edu.pl -- http://mail.python.org/mailman/listinfo/python-list
Re: Efficient way to sum a product of numbers...
31-08-2009 o 22:28:56 Jan Kaliszewski z...@chopin.edu.pl wrote: setup = from itertools import starmap, imap ; from operator import mul; import random, string; names = [rndom.choice(string. ascii_letters) for x in xrange(1)]; hours = [random.randint( 1, 12) for x in xrange(1000)]; m = zip(names, hours); workers = set(names); r = dict(zip(workers, (random.randint(1, 10) for x i n xrange(en(workers) Erratum -- should be: setup = ( ... 'from itertools import starmap, imap;' ... 'from operator import mul;' ... 'import random, string; names' ... ' = [random.choice(string.ascii_letters)' ... 'for x in xrange(1)];' ... 'hours = [random.randint(1, 12)' ... for x in xrange(1)];' ... 'm = zip(names, hours);' ... 'workers = set(names);' ... 'r = dict(zip(workers, (random.randint(1, 10)' ... ' for x in xrange(len(workers)' ... ) -- Jan Kaliszewski (zuo) z...@chopin.edu.pl -- http://mail.python.org/mailman/listinfo/python-list