【问题标题】:Is there a faster way to rebuild a dataframe based on certain values of rows?有没有更快的方法来根据行的某些值重建数据框?
【发布时间】:2022-12-01 07:33:13
【问题描述】:

我将一个包含大约 620k 行和 6 列的 .csv 文件加载到 jupyter notebook 中。 data 是这样的:

col_1   col_2   col_3   col_4       col_5
ID_1    388343  388684  T.45396D    2.400000e-03
ID_1    388343  388684  T.45708S    3.400000e-04
ID_1    388343  388684  T.48892G    2.200000e-10
ID_1    388343  388684  T.56898F    1.900000e-21
ID_1    388343  388684  T.64122D    2.300000e-04

我需要重建表,使 ID (col_1) 具有唯一性,最小值为 (col_5)。我所做的是:

for i in unique_col_1:
    index = data[(data['col_1'] == i)].index
    min_value = data.col_5.iloc[index].min()
    index = data[ (data['col_1'] == i) & (data['col_5'] != min_value) ].index
    data.drop(index, inplace=True)

但这太慢了,在我的机器上处理速度约为 6.5 it/s,而在 google colaboratory 上运行时为 8 it/s。

有没有更好的方法可以更快地做到这一点?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    可能不是最快的实现,但它肯定比遍历 col_1 的所有值并迭代删除它更快。

    df.sort_values("col_5").drop_duplicates(subset="col_1", keep=First)
    

    您的实施有两个主要的性能考虑因素:

    1. 矢量化:
      sort_valuesdrop_duplicates 等 pandas 函数和其他操作是用 cython(一个 python 扩展库,用于构建在 C 或 C++ 中运行的编译模块)编写的。这些函数比为大型数据集使用 for 循环编写的 python 代码快数百或数千倍。因此,只要有可能,立即对整个数组使用内置的 pandas 运算符,而不是自己循环遍历数据。
    2. 迭代数组大小调整:
      pandas 建立在 numpy 之上,并使用内存中的连续数组来存储数字数据列。分配这些数组(相对)较慢;对它们执行操作很快。调整数组大小时,需要再次重新分配并将数据复制到新调整大小的数组中。因此,当您遍历一个数组并在每次迭代中执行类似 dropappend 的操作(正是由于这个原因而被弃用)时,您将在每次迭代中重新分配整个数据帧的数组。更好的方法是构建一个要删除的数组索引列表,然后在循环结束时将它们全部删除一次;最好是使用矢量化解决方案并首先跳过 for 循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-14
      • 2014-01-11
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多