You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效遍历PhysioNet 2019文件并合并为单个DataFrame

PhysioNet 2019数据集合并代码优化

问题描述

我拥有PhysioNet 2019数据集,包含约40000份患者记录,每个文件对应一位患者,需要将所有数据合并为单个DataFrame。我了解到循环中不应直接拼接pandas DataFrame,应先存入列表再转换,但当前用np.append循环拼接numpy数组时,初期每秒100次迭代,后期仅5次/秒。请问能否优化代码?是否应改用普通Python列表替代numpy数组?

原有代码

for directory in tqdm(os.listdir(dir_path)):
    for file in tqdm(os.listdir(dir_path + '/'+ directory)):
        pat_path = dir_path + '/'+ directory + '/'+ file
        new_pat = pd.read_csv(pat_path,sep='|')
        new_pat['PatID'] = file[1:-4]
        new_pat = new_pat.to_numpy()
        physionet_2019 = np.append(physionet_2019, new_pat, axis=0)

physionet_2019 = pd.DataFrame(physionet_2019, columns= column_names)

问题根源

np.append每次调用都会创建一个新的numpy数组,将原有数组和新数据全部复制进去。随着数组体积不断增大,每次复制的时间成本会急剧上升,这就是后期迭代速度暴跌的核心原因。

优化方案

改用普通Python列表存储每个患者的数据(直接存DataFrame或numpy数组均可),因为列表的append操作是均摊O(1)时间复杂度,不会每次复制全部数据,最后再一次性合并,效率会大幅提升。

方案1:直接存储DataFrame(最简洁高效)

import os
import pandas as pd
from tqdm import tqdm

dir_path = "你的数据集路径"
column_names = ["你的列名列表"]

# 初始化列表存储每个患者的DataFrame
data_list = []

for directory in tqdm(os.listdir(dir_path)):
    dir_full_path = os.path.join(dir_path, directory)
    for file in tqdm(os.listdir(dir_full_path)):
        pat_path = os.path.join(dir_full_path, file)
        new_pat = pd.read_csv(pat_path, sep='|')
        new_pat['PatID'] = file[1:-4]
        data_list.append(new_pat)

# 一次性合并所有DataFrame
physionet_2019 = pd.concat(data_list, ignore_index=True)

方案2:存储numpy数组后合并

如果坚持用numpy数组,也可以先存入列表,最后用np.vstack一次性拼接:

import os
import numpy as np
import pandas as pd
from tqdm import tqdm

dir_path = "你的数据集路径"
column_names = ["你的列名列表"]

data_list = []

for directory in tqdm(os.listdir(dir_path)):
    dir_full_path = os.path.join(dir_path, directory)
    for file in tqdm(os.listdir(dir_full_path)):
        pat_path = os.path.join(dir_full_path, file)
        new_pat = pd.read_csv(pat_path, sep='|')
        new_pat['PatID'] = file[1:-4]
        data_list.append(new_pat.to_numpy())

# 一次性拼接所有数组
physionet_2019 = np.vstack(data_list)
physionet_2019 = pd.DataFrame(physionet_2019, columns=column_names)

额外优化建议

  • 使用os.path.join拼接路径,避免手动拼接字符串出现的路径分隔符问题
  • 若机器性能允许,可使用tqdm.contrib.concurrent.process_map实现并行读取,进一步提升速度

内容的提问来源于stack exchange,提问作者Ali Fayad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:56:03