2

I need to place all the elements from my first list to knth positions of the second list. Where k = 0,1,2... and n is a single number. Currently I am doing this (using numpy)

#create numpy array
positionList = np.array([])

positions = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

epochs = np.array([10, 11, 12])

for pos,epoch in zip(positions,epochs):
    position = np.insert(pos,0,epoch)

    if len(positionList) > 0:
        positionList = np.concatenate((positionList,position)) 
    else:
        positionList = position

positionList = np.around(positionList,1).tolist()
#expected output [10, 1, 2, 3, 11, 4, 5, 6, 12, 7, 8, 9]

Where positions is 2D. I am trying to find the most efficient possible (time and space) way to do this with numpy.

Note: The above code does work. I just want to make it efficient.

2 Answers2

2

Just use the axis parameter of np.concatenate():

import numpy as np


positions = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
epochs = np.array([10, 11, 12])
print(np.concatenate([epochs[..., None], positions], axis=1).ravel())
# [10  1  2  3 11  4  5  6 12  7  8  9]

No loops were harmed when writing this code.

norok2
  • 25,683
  • 4
  • 73
  • 99
1

If your input is actually two lists, there is no need to use NumPy here:

a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = [10, 11, 12]

print([z for x, y in zip(b, a) for z in [x] + y])
# [10, 1, 2, 3, 11, 4, 5, 6, 12, 7, 8, 9]
%timeit [z for x, y in zip(b, a) for z in [x] + y]
# 1000000 loops, best of 3: 1.04 µs per loop

or, if a is flat and you specify the break every n elements:

n = 3
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [10, 11, 12]

print([z for x, y in zip(b, zip(*[iter(a)] * n)) for z in (x,) + y])
# [10, 1, 2, 3, 11, 4, 5, 6, 12, 7, 8, 9]
%timeit [z for x, y in zip(b, zip(*[iter(a)] * n)) for z in (x,) + y]
# 1000000 loops, best of 3: 1.31 µs per loop

For comparison, here is the NumPy-based solution:

import numpy as np


a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([10, 11, 12])
print(np.concatenate([b[..., None], a], axis=1).ravel().tolist())
# [10, 1, 2, 3, 11, 4, 5, 6, 12, 7, 8, 9]
%timeit np.concatenate([b[..., None], a], axis=1).ravel().tolist()
# 100000 loops, best of 3: 2.43 µs per loop

These indicate that, at least for your inputs, the Python list-based solution are actually faster than resorting to NumPy.

norok2
  • 25,683
  • 4
  • 73
  • 99