0

I am given an array X and I am asked to return another array Y where y[t] = x[t] + x[t-1] and y[0] = 0 without using a for loop in Python.

What I can think of is using rolling sum but I am not sure if this is the fastest way since I need to convert x into a dataframe/ a series for rolling to work. Is there a faster way to do that? Thanks!

df = pd.DataFrame(X).rename(columns={0: 'X'})
df['Y'] = df['X'].rolling(2).sum().fillna(0)
Y = df['Y'].values
cs95
  • 379,657
  • 97
  • 704
  • 746
  • "without using a for loop" - but is list comprehension okay? – Stuart Oct 10 '18 at 18:46
  • This question should probably be on codereview.stackexchange.com ... stackoverflow is not good at providing a "faster" way of doing things in general – Joran Beasley Oct 10 '18 at 18:49
  • 1
    This is similar to https://stackoverflow.com/questions/28288252/fast-rolling-sum although the only answer there uses numpy. – Stuart Oct 10 '18 at 18:52

3 Answers3

1

You could use a list comprehension and zip:

x = [1, 2, 3, 4]
y = [0] + [c + n for c, n in zip(x, x[1:])]
print(y)

Output

[0, 3, 5, 7]

This approach relies on built-in functions, so no need to import an external module such as pandas.

Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
  • please complete the answer adding why this is or not a better approach – Mauricio Cortazar Oct 10 '18 at 18:47
  • its not better ... its also not worse ... for some data sets this might be faster... in others it maybe faster to convert to numpy or pandas ... and use their rolling average methods – Joran Beasley Oct 10 '18 at 18:48
  • it begs the question though of how a list comprehension is different from a loop (hint ... its not) or for that matter how `.rolling()` is just a loop also. These stupid "trick" questions that put nonsense restrictions on problems never really make sense – Joran Beasley Oct 10 '18 at 18:53
1

In case you are looking for one-liners might not give best performace

from toolz.itertoolz import sliding_window
[0]+map(sum,list(sliding_window(2, [1, 2, 3, 4]))) # [0, 3, 5, 7]
mad_
  • 8,121
  • 2
  • 25
  • 40
0

Well, you could use numpy, though that still turns the list into an array.

y = x + np.roll(x, 1)
y[0] = 0    

This is fast, short, fairly transparent and doesn't (explicitly) use a for loop.

You could also use map, which is pretty much the same as the list comprehension and doesn't require any external libraries.

y = 0 + map(lambda (a, b): a+b, zip(x, x[1:]))

In Python3 this doesn't work, and instead you would need to write:

y = [0] + list(map(lambda a: a[0]+a[1], zip(x, x[1:])))

or

y = [0] + list(map(sum, zip(x, x[1:])))
Stuart
  • 9,597
  • 1
  • 21
  • 30