如何在不复制的情况下从单个1D Numpy数组构造Pandas DataFrame

Pep*_*ijn 11 python numpy cython dataframe pandas

与我可以找到的其他每个问题不同,我不想从同构的Numpy数组创建DataFrame,也不想将结构化数组转换为DataFrame。

我想要的是为每列从单个1D Numpy数组创建一个DataFrame。我尝试了visible DataFrame({"col": nparray, "col": nparray}),但是它显示在我的个人资料的顶部,因此它的运行速度确实很慢。

据我了解,Pandas DataFrames是在纯Python中实现的,每个列均由Numpy数组支持,因此我认为有一种有效的方法。

我实际上想做的是从Cython高效地填充DataFrame。Cython具有允许有效访问Numpy阵列的内存视图。所以我的策略是分配一个Numpy数组,将其填充数据,然后将其放入DataFrame中。

相反的效果很好,可以从Pandas DataFrame创建一个memoryview。因此,如果有一种方法可以预分配整个DataFrame,然后仅将列传递给Cython,这也是可以接受的。

cdef int32_t[:] data_in = df['data_in'].to_numpy(dtype="int32")
Run Code Online (Sandbox Code Playgroud)

我的代码配置文件的一部分如下所示,其中通过在最后创建DataFrame完全使代码所做的一切相形见war。

         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)
Run Code Online (Sandbox Code Playgroud)

对应代码:

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,
    })
Run Code Online (Sandbox Code Playgroud)

Ara*_*ash 0

我可以建议一一添加列。它可能有助于提高效率。比如像这样,

import numpy as np
import pandas as pd

df = pd.DataFrame()

col1 = np.array([1, 2, 3])
col2 = np.array([4, 5, 6])

df['col1'] = col1
df['col2'] = col2
Run Code Online (Sandbox Code Playgroud)
>>> df
   col1  col2
0     1     4
1     2     5
2     3     6
Run Code Online (Sandbox Code Playgroud)