gpt4 book ai didi

python - 封装向量化函数 - 用于 Panda DataFrames

转载 作者:行者123 更新时间:2023-12-04 09:43:22 25 4
gpt4 key购买 nike

我一直在重构一些代码并使用它来探索如何在使用 Pandas 和 Numpy 时构建可维护、灵活、简洁的代码。 (通常我只是短暂地使用它们,我现在处于一个我应该瞄准成为前冲刺的角色。)

我遇到的一个例子是一个函数,有时可以在一列值上调用,有时在三列值上调用。使用 Numpy 的矢量化代码将其完美封装。但是使用它变得有点笨拙。

我应该如何“更好地”编写以下函数?

def project_unit_space_to_index_space(v, vertices_per_edge):
return np.rint((v + 1) / 2 * (vertices_per_edge - 1)).astype(int)


input = np.concatenate(([df['x']], [df['y']], [df['z']]), axis=0)

index_space = project_unit_space_to_index_space(input, 42)

magic_space = some_other_transformation_code(index_space, foo, bar)

df['x_'], df['y_'], df['z_'] = magic_space

正如所写的那样,该函数可以接受一列数据或多列数据,并且它仍然可以正确且快速地工作。

返回类型是直接传递给另一个类似结构的函数的正确形状,允许我巧妙地链接函数。

即使将结果分配回数据框中的新列也不是“糟糕的”,尽管它有点笨拙。

但是将输入打包为单个 np.ndarray确实非常非常笨重。

我还没有找到任何涵盖这一点的风格指南。它们到处都是 itterrows 和 lambda 表达式等。但我没有发现封装这种逻辑的最佳实践。

那么,你如何 构造上面的代码?

编辑:用于整理输入的各种选项的时序
%timeit test = project_unit_sphere_to_unit_cube(df[['x','y','z']].unstack().to_numpy())                      
# 1.44 ms ± 57.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit test = project_unit_sphere_to_unit_cube(df[['x','y','z']].to_numpy().T)
# 558 µs ± 6.25 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit test = project_unit_sphere_to_unit_cube(df[['x','y','z']].transpose().to_numpy())
# 817 µs ± 18.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit test = project_unit_sphere_to_unit_cube(np.concatenate(([df['x']], [df['y']], [df['z']]), axis=0))
# 3.46 ms ± 42.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

最佳答案

In [101]: df = pd.DataFrame(np.arange(12).reshape(4,3))                         
In [102]: df
Out[102]:
0 1 2
0 0 1 2
1 3 4 5
2 6 7 8
3 9 10 11

您正在从数据框的 n 列中创建一个 (n,m) 数组:
In [103]: np.concatenate([[df[0]],[df[1]],[df[2]]],0)                           
Out[103]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])

一种更紧凑的方法是转置这些列的数组:
In [104]: df.to_numpy().T                                                       
Out[104]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])

数据帧有自己的转置:
In [109]: df.transpose().to_numpy()                                             
Out[109]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])

您的计算适用于数据框,返回具有相同形状和索引的数据框:
In [113]: np.rint((df+1)/2 *(42-1)).astype(int)                                 
Out[113]:
0 1 2
0 20 41 62
1 82 102 123
2 144 164 184
3 205 226 246

一些 numpy函数将输入转换为 numpy数组并返回一个数组。其他人,通过将详细信息委托(delegate)给 pandas方法,可以直接在数据帧上工作,并返回一个数据帧。

关于python - 封装向量化函数 - 用于 Panda DataFrames,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62233061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com