arrays - Python: Creating an N-dimensional list from separate lists of varying sizes and dtypes -
say have these lists:
a = [1, 2, 3, 4] b = [6,7] c = ['a', 'b', 'c']
i create 3-dimensional data structure contains new lists combining elements of each list in possible ways. access these new list using matrix indexing.
so example, f function want. this:
m = f(a,b,c)
then m[0][0][0] give [1,6,'a'], m[1][0][0] give [2,6,'a'], , on.
basically, know can using nested loops.
jlist = [] j in a: klist = [] k in b: llist = [] l in c: o = [j,k,l] llist.append(o) klist.append(llist) jlist.append(klist)
this gives me list of lists of lists of lists.
[[[[1, 6, 'a'], [1, 6, 'b'], [1, 6, 'c']], [[1, 7, 'a'], [1, 7, 'b'], [1, 7, 'c']]], [[[2, 6, 'a'], [2, 6, 'b'], [2, 6, 'c']], [[2, 7, 'a'], [2, 7, 'b'], [2, 7, 'c']]], [[[3, 6, 'a'], [3, 6, 'b'], [3, 6, 'c']], [[3, 7, 'a'], [3, 7, 'b'], [3, 7, 'c']]], [[[4, 6, 'a'], [4, 6, 'b'], [4, 6, 'c']], [[4, 7, 'a'], [4, 7, 'b'], [4, 7, 'c']]]]
this fine, have dimensions higher 3, , many nested loops seems can't possibly best or efficient way build type of data structure. can't thinking there must better solution, in library function made above, maybe numpy function, i've done lot of searching , have not found lists of varying sizes , data types have.
any ideas?
you can use itertools.product
take cartesian product of lists, use numpy.reshape
reshaping, taking last dimension number of lists, length of innermost list , until length of outermost:
>>> args = a,b,c >>> np.array(list(product(*args))).reshape(len(a), len(b), len(c), len(args)) array([[[['1', '6', 'a'], ['1', '6', 'b'], ['1', '6', 'c']], [['1', '7', 'a'], ['1', '7', 'b'], ['1', '7', 'c']]], [[['2', '6', 'a'], ['2', '6', 'b'], ['2', '6', 'c']], [['2', '7', 'a'], ['2', '7', 'b'], ['2', '7', 'c']]], [[['3', '6', 'a'], ['3', '6', 'b'], ['3', '6', 'c']], [['3', '7', 'a'], ['3', '7', 'b'], ['3', '7', 'c']]], [[['4', '6', 'a'], ['4', '6', 'b'], ['4', '6', 'c']], [['4', '7', 'a'], ['4', '7', 'b'], ['4', '7', 'c']]]], dtype='<u21')
you can generate shape on fly using: tuple(map(len, args)) + (len(args),)
(suggested @stevenrumbalski), have:
>>> np.array(list(product(*args))).reshape(tuple(map(len, args)) + (len(args),))
or:
>>> np.array(list(product(*args))).reshape(tuple(map(len, args)) + (-1,))
without needing specify last dimension.
Comments
Post a Comment