选择一张Pandas数据框中的1.6M行。

10 浏览
0 Comments

选择一张Pandas数据框中的1.6M行。

这个问题已经有了答案

\"Large data\" workflows using pandas [closed]

我有一个包含 ~2.3M 行数据的 csv 文件。我想要保存数据帧中两列中有非 nan 值的行的子集 (~1.6M) 。我想继续使用 pandas 来完成这个任务。现在,我的代码看起来像:

import pandas as pd
catalog = pd.read_csv('catalog.txt')
slim_list = []
for i in range(len(catalog)):
    if (pd.isna(catalog['z'][i]) == False and pd.isna(catalog['B'][i]) == False):
        slim_list.append(i)

它保存了具有非 nan 值的行的 catalog。然后用那些行作为条目创建一个新的 catalog。

slim_catalog = pd.DataFrame(columns = catalog.columns)
for j in range(len(slim_list)):
    data = (catalog.iloc[j]).to_dict()
    slim_catalog = slim_catalog.append(data, ignore_index = True)
pd.to_csv('slim_catalog.csv')

原则上,这应该可以工作。读取每一行为字典使它稍微加速了一些。然而,对于 2.3M 行数据执行这个过程需要太长太久了。有没有更好的解决方法?

admin 更改状态以发布 2023年5月24日
0
0 Comments

必须强调,这是pandas中完全错误的做法

首先,绝对不要在循环中使用某个范围进行迭代,例如for i in range(len(catalog)):,然后逐个索引行:catalog['z'][i]。这是极其低效的。

其次,不要在循环中使用pd.DataFrame.append来创建pandas.DataFrame,这是一个线性操作,会导致整个操作的时间复杂度呈现平方级增长。

但事实上,你根本不需要在这里循环。你只需要使用如下所示的方式:

catalog[catalog.loc[:, ['z', 'B']].notna().all(axis=1)].to_csv('slim_catalog.csv')

或者,为了更加易读一些,可以把它分开写:

not_nan_zB = catalog.loc[:, ['z', 'B']].notna().all(axis=1)
catalog[not_nan_zB].to_csv('slim_catalog.csv')

0