2

I have a numpy array of an image, but it's not complete, it look like this :

[
[255,255,255],
[128],
[34,4],
[44]
]

I want to to add the previous value of specific element to completed that elements, like this:

[
[255,255,255],
[128,128,128],
[34,4,4],
[44,44,44]
]

so, how can i add values to specific element? The point is, I need each element block to complete its self

2 Answers2

4

Approach #1

Here's one based on this post -

def fill_by_last_val(a):
    lens = np.array([len(item) for item in a])
    ncols = lens.max()
    last_ele = np.array([a_i[-1] for a_i in a])
    out = np.repeat(last_ele[:,None],ncols,axis=1)
    mask = lens[:,None] > np.arange(lens.max())
    out[mask] = np.concatenate(a)
    return out

Approach #2

Another based on itertools -

import itertools

def fill_by_last_val_v2(a):
    last_ele = np.array([a_i[-1] for a_i in a])
    a_f = np.array(list(itertools.zip_longest(*a,fillvalue=0))).T
    m = np.minimum.accumulate((a_f==0)[:,::-1],axis=1)[:,::-1]
    return m*last_ele[:,None]+a_f

Approach #3

Another with pandas dataframe assuming no NaNs in the input -

import pandas as pd

def fill_by_last_val_v3(a):
    df = pd.DataFrame(a)
    m = df.isnull()
    last_ele = np.array([a_i[-1] for a_i in a])
    return np.where(m,last_ele[:,None],df)

Approach #4

Simplest of the lot with pandas again -

In [168]: a
Out[168]: [[255, 255, 255, 5], [128, 5, 6], [34, 0, 7], [nan, 44]]

In [169]: pd.DataFrame(a).ffill(axis=1).to_numpy()
Out[169]: 
array([[255., 255., 255.,   5.],
       [128.,   5.,   6.,   6.],
       [ 34.,   0.,   7.,   7.],
       [ nan,  44.,  44.,  44.]])

You might want to do dtype conversion though to have the original datatype for pandas solutions.

Divakar
  • 218,885
  • 19
  • 262
  • 358
1

I made a quick solution that might work with what you require:

A = np.array([[255,255,255],
              [128],
              [34,4],
              [44]])

# lenA can be changed depending on the preferred dimensions
lenA = len(A) - 1 
np.array([b if len(b) == lenA else b + [b[-1]]*(lenA - len(b)) for b in A])

Let me know if that's enough or there are more details that you can share.

jtitusj
  • 3,046
  • 3
  • 24
  • 40
  • I try your answer and I get more value than expected. May be add lenA = len(A) -1. – Adam Bellaïche Nov 25 '19 at 15:31
  • yes, it worked, but i miss-phrased the question, i don't want the array n*n, I just want the elements be the same fixed length, 3 for an example. thank you so much – Jamal Alqale Nov 25 '19 at 16:03
  • @jtitusj Please leave some feedback with your downvote(s). It would be helpful if you have some constructive criticism, so that authors can improve upon. – Divakar Nov 25 '19 at 18:42