选择一张Pandas数据框中的1.6M行。
选择一张Pandas数据框中的1.6M行。
这个问题已经有了答案:
我有一个包含 ~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日
必须强调,这是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')