У меня большой набор данных, состоящий из миллионов строк и около 6 столбцов. Данные в настоящее время находятся в фрейме данных Pandas, и я ищу самый быстрый способ работы с ним. Например, допустим, я хочу отбросить все строки, в которых значение в одном столбце равно «1».
Вот мой минимальный рабочий пример:
# Create dummy data arrays and pandas dataframe
array_size = int(5e6)
array1 = np.random.rand(array_size)
array2 = np.random.rand(array_size)
array3 = np.random.rand(array_size)
array_condition = np.random.randint(0, 3, size=array_size)
df = pd.DataFrame({'array_condition': array_condition, 'array1': array1, 'array2': array2, 'array3': array3})
def method1():
df_new = df.drop(df[df.array_condition == 1].index)
РЕДАКТИРОВАТЬ: Как указал Генри Йикв комментариях более быстрый подход Pandas заключается в следующем:
def method1b():
df_new = df[df.array_condition != 1]
Я считаю, что Pandas может быть довольно медленным в такого рода вещах, поэтому я также реализовал метод, использующий numpy, обрабатывая каждый столбец как отдельныймассив:
def method2():
masking = array_condition != 1
array1_new = array1[masking]
array2_new = array2[masking]
array3_new = array3[masking]
array_condition_new = array_condition[masking]
И результаты:
%timeit method1()
625 ms ± 7.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit methodb()
158 ms ± 7.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit method2()
138 ms ± 3.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Таким образом, мы видим небольшое значительное повышение производительности при использовании numpy. Однако это происходит за счет гораздо менее читаемого кода (т. Е. Необходимости создавать маску и применять ее к каждому массиву). Этот метод также не выглядит настолько масштабируемым, как если бы у меня было, скажем, 30 столбцов данных, мне понадобится много строк кода, которые применяют маску к каждому массиву! Кроме того, было бы полезно разрешить необязательные столбцы, чтобы этот метод мог не работать при работе с пустыми массивами.
Поэтому у меня есть 2 вопроса:
1) Есть ли очиститель? / более гибкий способ реализовать это в numpy?
2) Или лучше, есть ли способ более высокой производительности, который я мог бы использовать здесь? например, JIT (numba?), Cython или что-то еще?
PS, на практике можно использовать операции на месте, заменяя старый массив новым после удаления данных