I have two large one-dimensional numpy arrays (~1e8+ elements) of the same size. Array 1 (a1) is an integer indicator value, it tells me the meaning of the values in a2. Array 2 (a2) has measurement values. I want to separate the values in a2, based on the values in a1. I want to iterate over a list of possible values in a1 and select corresponding values (by index) from a2. Because of the data size and the number of different times I have to do this, it needs to be as fast as possible.
Here's a simple example to hopefully explain my problem more clearly:
a1 = [0, 2, 1, 1, 0, 2] # actual values range from 0 to 4095
a2 = [0.5, 2.4, 1.0, 1.2, 0.4, 2.6] # dummy values for example
I would like to separate the values in a2 based on the values in a1. I am saving each separated array into an HDF5 dataset. So, in the end, I need an array for each value in a1
out = [0.5,0.4] # a1 == 0
out = [1.0, 1.2] # a1 == 1
out = [2.4, 2.6] # a1 == 2
Currently, I've tried the following:
import numpy as np
size = int(1e8)
a1 = np.random.randint(0, 4096, size=size)
a2 = np.random.rand(size)
for i in range(0, 4096):
ind = a1 == i
out = a2[ind]
# more code here to save out to h5 file
Based on some timeit testing, np.extract works just slightly faster than this boolean masking approach for large arrays:
import numpy as np
size = int(1e8)
a1 = np.random.randint(0, 4096, size=size)
a2 = np.random.rand(size)
for i in range(0,4096):
ind = a1 == i
out = np.extract(ind, a2)
# more code here to save out to h5 file
I also tried putting this into a pandas series with a1 as the index, but this was much slower.
import pandas as pd
import numpy as np
size = int(1e8)
a1 = np.random.randint(0, 4096, size=size)
a2 = np.random.rand(size)
s = pd.Series(a2, index=a1)
for i in range(0,4096):
out = s.loc[i] #this is WAY slower than numpy
# more code here to save out to h5 file
I'm wondering if there's a faster way of doing this? Maybe with sorting and searchsorted? Is it possible to generate a "database-like index" for a numpy array?