1

I have three numpy arrays:

Arr1 = [9,7,3,1]       (1 x 4 array)
Arr2 = [[14,6],[13,2]] (2 x 2 array)
Arr3 = [0,2]           (1 x 2 array)

I need to replace the elements in Arr1 with the elements in Arr2 with the corresponding indices given in Arr3, such that the output would be:

Output_Arr = [[14,6],[7],[13,2],[1]]

I've written some code that I think is a good start, but it's not working. No errors or anything, just the Arr1 is not updating as if the criteria is not satisfied:

dim1 = len(Arr1)
dim2 = len(Arr2)
dim3 = len(Arr3)

for i in range(dim1):
    for j in range(dim3):
        if i==Arr3[j]:
            Arr1[i] = Arr2[j]
        else:
            Arr1[i] = Arr1[i]

Does anyone have any ideas of how to go about this?

Melanie
  • 109
  • 1
  • 9
  • 1
    output_arr cannot be numpy array, as all lines don't have the same length. Could you clarify? (I mean: are you ok if it's just a list of list? or do you want zeros as fill_values ?) – Demi-Lune Nov 24 '21 at 13:13
  • @Demi-Lune good call. A list would work fine, such that the output is an "array of arrays". – Melanie Nov 24 '21 at 13:17

2 Answers2

1

you can do it with list comprehension, which will save you some code lines and make it more interpretable, though it won't improve the runtime, as it uses loops under the hood. Also note that by incorparating a varying length lists, you'll loose any runtime improvements of the NumPy library, as to do so it is being cast to dtype=object

Arr1 = np.array([9,7,3,1], dtype=object)

Arr2 = np.array([[14,6], [1], [13,2]], dtype=object)

Arr3 = np.array([0,2])

result = np.array([[Arr1[i]] if not np.sum(Arr3 == i) else Arr2[i] for i in np.arange(Arr1.size)], dtype=object)

result
OUTPUT: array([list([14, 6]), list([7]), list([13, 2]), list([1])], dtype=object)

Cheers

Michael
  • 2,167
  • 5
  • 23
  • 38
  • Despite the names, none of his code samples are arrays. They are lists! – hpaulj Nov 24 '21 at 16:26
  • @hpaulj Yes, this is because you add arrays of different shapes, so the `numpy.array` must resort the `python`-like behavior, which is exactly storing numbers in `list` objects. That is exactly the reason I said that in this case (i.e., when using arrays of different shapes) you loose the benifits of the `NumPy` library. What is your objection? – Michael Nov 24 '21 at 17:35
0

Your code produces a list

In [505]: Arr1 = [9,7,3,1]
     ...: Arr2 = [[14,6],[13,2]]
     ...: Arr3 = [0,2]
     ...: 
     ...: 
In [506]: dim1 = len(Arr1)
     ...: dim2 = len(Arr2)
     ...: dim3 = len(Arr3)
     ...: 
     ...: for i in range(dim1):
     ...:     for j in range(dim3):
     ...:         if i==Arr3[j]:
     ...:             Arr1[i] = Arr2[j]
     ...:         else:
     ...:             Arr1[i] = Arr1[i]
     ...: 
In [507]: Arr1
Out[507]: [[14, 6], 7, [13, 2], 1]

You could tweak that by changing to Arr1[i] = [Arr1[i]]

If I change Arr1 and Arr2 to arrays, I do get an error

Arr1=np.array([9,7,3,1])
...
ValueError: setting an array element with a sequence.

Trying to put a np.array([14,6]) into a slot of a numeric array is not allowed.

Changing Arr1 to object dtype, does work:

In [511]: Arr1=np.array(Arr1,object)
...
In [513]: Arr1
Out[513]: array([array([14,  6]), 7, array([13,  2]), 1], dtype=object)

So I'm surprised that you didn't either get an error, or at least some sort of change.

hpaulj
  • 221,503
  • 14
  • 230
  • 353