В отличие от любого другого вопроса, который я могу найти, я не хочу создавать DataFrame из однородного массива Numpy, а также не хочу преобразовывать структурированный массив в DataFrame.
Я хочу создатьDataFrame из отдельных массивов 1D Numpy для каждого столбца.Я попробовал очевидное DataFrame({"col": nparray, "col": nparray})
, но это отображается вверху моего профиля, поэтому он должен делать что-то очень медленное.
Насколько я понимаю, Pandas DataFrames реализованы на чистом Python, где каждый столбецподдерживается массивом Numpy, поэтому я думаю, что есть эффективный способ сделать это.
Что я на самом деле пытаюсь сделать, так это эффективно заполнить DataFrame из Cython.У Cython есть представления памяти, которые обеспечивают эффективный доступ к массивам Numpy.Поэтому моя стратегия состоит в том, чтобы выделить массив Numpy, заполнить его данными, а затем поместить в DataFrame.
Обратное работает довольно хорошо, создавая представление памяти из DataFrame Pandas.Так что, если есть способ предварительно выделить весь DataFrame, а затем просто передать столбцы в Cython, это также допустимо.
cdef int32_t[:] data_in = df['data_in'].to_numpy(dtype="int32")
Раздел профиля моего кода выглядит следующим образом, где весь кодdo полностью затмевается созданием DataFrame в конце.
1100546 function calls (1086282 primitive calls) in 4.345 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 4.345 4.345 profile:0(<code object <module> at 0x7f4e693d1c90, file "test.py", line 1>)
445/1 0.029 0.000 4.344 4.344 :0(exec)
1 0.006 0.006 4.344 4.344 test.py:1(<module>)
1000 0.029 0.000 2.678 0.003 :0(run_df)
1001 0.017 0.000 2.551 0.003 frame.py:378(__init__)
1001 0.018 0.000 2.522 0.003 construction.py:170(init_dict)
Соответствующий код:
def run_df(self, df):
cdef int arx_rows = len(df)
cdef int arx_idx
cdef int32_t[:] data_in = df['data_in'].to_numpy(dtype="int32")
data_out_np = np.zeros(arx_rows, dtype="int32")
cdef int32_t[:] data_out = data_out_np
for arx_idx in range(arx_rows):
self.cpp_sec_par.run(data_in[arx_idx],data_out[arx_idx],)
return pd.DataFrame({
'data_out': data_out_np,
})