4 ms·
>>> arrays = [np.arange(1000)]*10 >>> zip_arrays(arrays) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2,
by PartiallyTyped 5y ago
>>> arrays = [np.arange(1000)]*10
>>> zip_arrays(arrays)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in zip_arrays2
File "<stdin>", line 2, in <listcomp>
File "<__array_function__ internals>", line 180, in concatenate
ValueError: zero-dimensional arrays cannot be concatenated
Try this:
def zip_arrays(arrays):
return np.concatenate([array[:l,...,None] for l in [min(array.shape[0] for array in arrays)] for array in arrays], axis=-1)
Or if we are trying to be more tidy instead of a one liner
def zip_arrays(arrays):
l = min(a.shape[0] for a in arrays)
arrays = [a[:l, ..., None] for a in arrays]
return np.concatenate(arrays)
- johndough 5y agoI think a more Pythonic solution would be np.array(arrays).T or maybe np.copy(arrays).T for one less character. The shortest solution is probably np.c_[arrays].T but likely causes a Google search on first read.
- PartiallyTyped 5y agoThat does not zip though. In fact, it creates a 1-dimensional array of objects because the arrays do not have the same number of items. >>> a = [np.arange(i) for i in range(1, 11)] >>> np.array(a).T array([array([0]), array([0, 1]), array([0, 1, 2]), array([0, 1, 2, 3]), array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4, 5]), array([0, 1, 2, 3, 4, 5, 6]), array([0, 1, 2, 3, 4, 5, 6, 7]), array([0, 1, 2, 3, 4, 5, 6, 7, 8]), array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])], dtype=object) In fact, if we are to zip them, it should yield: >>> list(zip(*a)) [(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)] zip_arrays otoh does give the same result. >>> zip_arrays(a) array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
- johndough 5y agoYou are completely right. Nevertheless, when I zip over arrays of different length, it is usually a bug instead of being intentional. A code-golfed version for different array lengths: np.c_[[a[:min(map(len,arrays))].T for a in arrays]].T The trick to get a local variable within a list comprehension statement with for l in [foo()] from your zip_array function is very cool by the way, but I sacrificed it in favor of shorter code.
- PartiallyTyped 5y agoI like your your solution, I think using `a[0:min(map(len,arrays))]` (ie with 0) is faster because it returns a slice and not a copy of the array. I am glad you liked the trick!
- kzrdude 5y agoI'm used to numpy and I can't understand np.c_ even with the docs. It says "Translates slice objects to concatenation along the second axis." but the examples pass in a list of arrays and use no slice objects (the builtin slice, I'm assuming)? If there was an example using just `np.c_[1:5, 11:15]` it would make sense. But clearly np.c_'s meaning has been extended beyond slices in some way. (Maybe I'm coming closer to understanding, but still miffed about the misleading doc.)
- m00dy 5y agowell, I used the code from Copilot :)