python - Pythonic way of calculating A x A' (without numpy) -
so list of list containing 0's , 1's . pythonic (and fast) way of calculating * a' without using nympy or scipy.
the numpy equivalent of above be:
def foo(a): return * a.t
if bitarray
can't installed, 1d solution in dot product in python without numpy can used same nested comprehension (https://stackoverflow.com/a/35241087/901925). not take advantage of 0/1 nature of data. it's exercise in nested iterations.
def dot1d(a,b): return sum(x*y x,y in zip(a,b)) def dot_2cmp(a): return [[dot1d(r,c) c in a] r in a]
itertools.product
can used iterate on row , column combinations, result 1d list, needs grouped (but step fast):
def dot2d(a): aa=[dot1d(x,y) x,y in itertools.product(a,a)] return [aa[i::len(a)] in range(len(a))]
testing:
a=[[1,0,1,0],[0,1,0,1],[0,0,1,1],[1,1,0,0]] in [246]: dot2d(a) out[246]: [[2, 0, 1, 1], [0, 2, 1, 1], [1, 1, 2, 0], [1, 1, 0, 2]] in [247]: dot_2cmp(a) out[247]: [[2, 0, 1, 1], [0, 2, 1, 1], [1, 1, 2, 0], [1, 1, 0, 2]] in [248]: np.dot(np.array(a),np.array(a).t).tolist() out[248]: [[2, 0, 1, 1], [0, 2, 1, 1], [1, 1, 2, 0], [1, 1, 0, 2]]
in timings on larger list, 2 list operations take same time. array version, in/out array conversion considerably faster.
in [254]: b=np.random.randint(0,2,(100,100)).tolist() in [255]: timeit np.dot(np.array(b),np.array(b).t).tolist() 100 loops, best of 3: 5.46 ms per loop in [256]: timeit dot2d(b) 10 loops, best of 3: 177 ms per loop in [257]: timeit dot_2cmp(b) 10 loops, best of 3: 177 ms per loop
the result symmetric, might worth effort skip duplicate calculations. mapping them on nested list more work in numpy
.
in [265]: timeit [[dot1d(r,c) c in b[i:]] i,r in enumerate(b)] 10 loops, best of 3: 90.1 ms per loop
for it's worth don't consider of these solutions 'more pythonic' others. long written in clear, running, python pythonic.
Comments
Post a Comment