简体   繁体   English

将 numpy 数组重塑为类似于具有任意嵌套子数组的不同数组

[英]Reshaping numpy array to be similar to different array with arbitrarily nested subarrays

I have two arrays a and b .我有两个 arrays ab If I run a.shape I get (10,) and if I run (b.shape) I get (10,) however each of those values are arbitrarily nested arrays which are not equal in shape to the others in itself or to the corresponding value in the other array.如果我运行a.shape我得到(10,)并且如果我运行(b.shape)我得到(10,)但是这些值中的每一个都是任意嵌套的 arrays ,它们在形状上不等于其他本身或另一个数组中的对应值。 For example a[0].shape returns (122,) and b[0].shape returns (3900,) and b[5].shape returns (5200,64) so they aren't even consistent within the same array.例如a[0].shape返回(122,)b[0].shape返回(3900,)b[5].shape返回(5200,64)因此它们在同一个数组中甚至不一致。

I know that they have the same total number of elements using the recursive solution found at Iterating through a multidimensional array in Python (no standard numpy functions seemed to be able to drill as deeply as necessary into the arrays):我知道它们使用在迭代 Python中找到的递归解决方案具有相同的元素总数(没有标准的 numpy 函数似乎能够尽可能深入地钻入数组):

def iterThrough(lists):
  if not hasattr(lists[0], '__iter__'):
    for val in lists:
      yield val
  else:
    for l in lists:
      for val in iterThrough(l):
        yield val
            si = 0

for value in iterThrough(a): #and b
    si += 1

Both return 3066752 .两者都返回3066752 I understand that this is quite messy, but I need it to be in that shape to compute a mathematical function later on and I'm guessing it's easier to to do this than to rewrite that equation to reflect a nicely formatted array.我知道这很混乱,但是我需要它处于那种形状才能稍后计算数学 function,我猜这样做比重写该方程以反映格式良好的数组更容易。

How can I make array a exactly identical in all its nested shapes to array b ?如何使数组a在其所有嵌套形状中与数组b完全相同?

Here's a solution that does the job, but is guaranteed to be slow, because it is recursive, iterative, and vectorizes nothing at all:这是一个可以完成这项工作的解决方案,但保证速度很慢,因为它是递归的、迭代的,并且根本不向量化:

import copy

# Generator function:
# Returns successive scalars from any crazily nested array
def arr_values(arr):
    for elem in arr:
        if (isinstance(elem, np.ndarray)):
            for sub_arr_elem in arr_values(elem):
                yield sub_arr_elem
        else:
            yield elem

# Generator function:
# Returns successive tuples (vector, index) from any arbitrarily nested array,
# such that assigning a value to vector[index] is the same as assigning the value
# to a position in the input array.
def arr_positions(arr):
    for pos,elem in enumerate(arr):
        if (isinstance(elem, np.ndarray)):
            for inner_arr_pos in arr_positions(elem):
                yield inner_arr_pos
        else:
            yield arr, pos

# Create a new array, having the shape of `b` (and incidentally, b's data also)
arr_in_shape_of_b = copy.deepcopy (b)

# Get the iterator for successive assignable positions in
# our destination array
iter_dest = arr_positions(arr_in_shape_of_b)

# Get the iterator for successive scalars from our source array
iter_src = arr_values(a)

# Now, iterate over the two iterators in tandem, and
# perform assignment of successive values from source,
# into successive positions in destination.
for ((dest_vec, pos), val) in zip(iter_dest, iter_src):
    dest_vec[pos] = val

Testing it out:测试一下:

I tested with this demo data for a , and b :我用这个演示数据测试了ab

a = np.array ([np.arange(6).reshape(2,3), np.array([np.arange(8).astype(np.ndarray),
                                                    23], dtype=np.ndarray),24], dtype=np.ndarray)
print (a.shape)
print (a)

b = np.roll(-1 * a, 2, axis=0)
print (b.shape)
print (b)

So, the input arrays a and b look like this:因此,输入 arrays ab如下所示:

(3,)
[array([[0, 1, 2],
       [3, 4, 5]])
 array([array([0, 1, 2, 3, 4, 5, 6, 7], dtype=object), 23], dtype=object)
 24]
(3,)
[array([array([0, -1, -2, -3, -4, -5, -6, -7], dtype=object), -23],
      dtype=object)
 -24 array([[ 0, -1, -2],
       [-3, -4, -5]])]

The output looks like this: output 看起来像这样:

(3,)
[array([array([0, 1, 2, 3, 4, 5, 0, 1], dtype=object), 2], dtype=object) 3
 array([[ 4,  5,  6],
       [ 7, 23, 24]])]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM