Python Pandas:基于时间戳合并多个CSV文件的实现及代码空DataFrame问题排查
解决CSV合并后DataFrame为空的问题
嘿,我来帮你拆解下这个问题,你遇到的空DataFrame其实是Pandas里一个很常见的小误区,咱们一步步来解决:
1. 代码里的错误 & 2. 为什么big_df一直是空的
核心问题就出在big_df.append(df)这一行!
Pandas的append()方法不会修改原有的DataFrame对象——它会创建并返回一个包含合并后数据的新DataFrame。你现在只是调用了append,但完全没有把返回的结果赋值回big_df,所以你初始化的那个空big_df自始至终都没被更新过,自然输出一直是空的。
举个极简例子就能看明白:
df1 = pd.DataFrame({'a': [1]}) df2 = pd.DataFrame({'a': [2]}) df1.append(df2) # 这行返回了新的df,但你没存下来 print(df1) # 还是原来的df1,输出只有[1]
哪怕你写成big_df = big_df.append(df)能解决空的问题,但这种循环append的方式效率极低——每次append都会创建新的DataFrame,253个文件下来会浪费很多内存和时间。
3. 优化后的代码实现
我给你写了一个更高效、更健壮的版本,不仅能解决空DataFrame的问题,还能帮你处理列名、时间戳排序这些实际需求:
import pandas as pd import os def check_path(infile): return os.path.exists(infile) # 获取正确的文件路径 first_entry = input('Tell me the path where your csv files are located at: ') while not check_path(first_entry): print('\nThis PATH is invalid!') first_entry = input('Tell me the RIGHT PATH in which your csv files are located: ') # 用列表存储所有读取的DataFrame,比循环append高效N倍 df_list = [] # 给数据定义列名,后续处理更清晰 column_names = [ 'timestamp', 'open', 'high', 'low', 'close', 'ignore_1', 'close_timestamp', 'ignore_2', 'ignore_3', 'ignore_4', 'ignore_5', 'ignore_6' ] for filename in os.listdir(first_entry): if filename.endswith(".csv"): print(f"Processing {filename}...") # 用os.path.join拼接路径,避免手动加\导致的错误,兼容Windows/Linux file_path = os.path.join(first_entry, filename) # 读取CSV:指定列名、空格分隔符(你的数据是空格分开的) df = pd.read_csv(file_path, header=None, names=column_names, sep='\s+') # 只保留需要的列,减少内存占用 df = df[['timestamp', 'open', 'high', 'low', 'close']] # 把Unix毫秒时间戳转成可读的datetime格式(可选,但后续分析超方便) df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms') df_list.append(df) # 一次性合并所有DataFrame,然后按时间戳排序 big_df = pd.concat(df_list, ignore_index=True) big_df = big_df.sort_values(by='timestamp').reset_index(drop=True) print("\nFinal merged DataFrame preview:") print(big_df.head()) # 可选:把合并后的结果保存到CSV # big_df.to_csv(os.path.join(first_entry, 'merged_aliceusdt_1h.csv'), index=False)
关键优化点说明:
- 用
pd.concat()替代循环append():concat是一次性合并所有DataFrame,避免了循环中频繁创建新对象的开销,处理253个文件会快很多。 - 路径安全处理:
os.path.join()自动适配操作系统的路径分隔符,不会出现手动加\导致的路径错误。 - 明确列名与分隔符:你的数据是空格分隔的,
sep='\s+'能正确识别每一列;给列命名后,后续筛选、分析数据更直观。 - 过滤无用列:直接保留你需要的时间戳和开高低收数据,减少内存占用。
- 时间戳格式化:把毫秒级Unix时间转成datetime类型,方便后续做时间序列分析(比如按日期筛选、计算收益率等)。
- 强制按时间排序:即使文件名的顺序不是严格时间顺序,合并后的DataFrame也会按时间戳从小到大排列,保证数据的时序正确性。
内容的提问来源于stack exchange,提问作者NoahVerner
相关产品推荐
相关产品推荐

