4

I have an interesting case. In column FID2 I have some values, based on each i'd like to create a list. The column Ncircles determines the list. For example:

  • If there's a value 0 in Ncircles, i'd like to create a list based on the value in FID2 in the same row as [i], where i is equal to FID2.
  • If there's a value 1 in Ncircles, i'd like to create a list based on the value in FID2 in the same row as [i-1, i, i +1], where i is equal to FID2.
  • If there's a value 3 in Ncircles, i'd like to create a list based on the value in FID2 in the same row as [i-3, i-2, i -1 i, i+1, i+2, i +3], where i is equal to FID2.

This is an example of df:

          FID2  Ncircles
0        50141         0
1        56188         1
2        75035         0
3        94937         3

The final lists can be written all in the same, one list. Do you have any suggestions how to do this?

An expected output would be a new list:

Newlist = [50141, 56187, 56188, 56188, 75035, 94934, 94935, 94936, 94937, 94938, 94939, 94940]
energyMax
  • 419
  • 1
  • 8
  • 16

2 Answers2

4

Use range in list comprehension with flattening:

Newlist = [c for a, b in zip(df['FID2'], df['Ncircles']) for c in range(a-b, a+b+1)]
print (Newlist)
[50141, 56187, 56188, 56189, 75035, 94934, 94935, 94936, 94937, 94938, 94939, 94940]
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
3

An approach using apply:

def create_list(ncircles, fid2):
    return [fid2 + k for k in range(-ncircles, ncircles+1)]

df['fid2list'] = df.apply(axis=1, func=lambda l: create_list(l.Ncircles, l.FID2))

    FID2  Ncircles                                           fid2list
0  50141         0                                            [50141]
1  56188         1                              [56187, 56188, 56189]
2  75035         0                                            [75035]
3  94937         3  [94934, 94935, 94936, 94937, 94938, 94939, 94940]

And the lists can be combined with np.concatenate(df['fid2list'].values):

array([50141, 56187, 56188, 56189, 75035, 94934, 94935, 94936, 94937,
   94938, 94939, 94940])
ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • This works great! But it fails for me, if i have a condition e.g. `[i-2490,i-2489,i-2488,i-1,i+1,i+2488,i+2489,i+2490]` since i cannot put this in a `range` function. Can you please make a suggestion how to approach this? – energyMax Feb 23 '19 at 08:01
  • @energyMax I don't quite understand the logic/pattern in `[i-2490,i-2489,i-2488,i-1,i+1,i+2488,i+2489,i+2490]`. Omitting the `i-1` and `i+1` part, it would be as simple as `return [fid2 - (2487 - k) for k in range(-ncircles, ncircles+1)]` (or something similar) . What's the value of `ncircles` in that example? – ernest_k Feb 23 '19 at 08:09
  • If I may, in case i have a list `[(50141, 56187, 56188, 56189), 75035, 94934, 94935]`, how can I extract values in a single `list` without `()`? – energyMax Feb 23 '19 at 09:19
  • @energyMax Check this: https://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists – ernest_k Feb 23 '19 at 09:22