Python处理多文件夹文本文件:时间匹配与DataFrame合并问题排查
解决file1时间匹配file2范围后label全为NaN的问题
问题核心分析
你的label全为NaN,本质是file1的时间戳没有匹配到file2中任何一个时间范围,大概率是以下原因:
- 时间格式不统一:file1和file2的时间列类型不一致(比如一个是字符串,一个是Unix时间戳数值;或者日期格式不兼容)
- 范围匹配逻辑错误:比如错误地用了单一行的范围判断,没遍历file2所有时间区间
- 文件读取异常:读取时未指定正确的分隔符,导致时间列读取错误
解决方案步骤
1. 统一时间格式为datetime类型
先把file1的时间列和file2的开始/结束时间列全部转为pandas的datetime类型,确保格式一致。
2. 正确实现多时间范围匹配
不要用单一的布尔判断,而是遍历file2的所有时间区间,或者用更高效的merge_asof方法(适合有序时间序列)。
3. 确保文件路径与读取逻辑正确
批量遍历文件夹时,确认每个子文件夹下的file1和file2都被正确读取,列数符合预期。
修正后的完整代码
import pandas as pd import os # 主文件夹路径 main_dir = "./user" all_dfs = [] # 遍历1-80个子文件夹 for folder_num in range(1, 81): folder_path = os.path.join(main_dir, str(folder_num)) file1_path = os.path.join(folder_path, "file1") file2_path = os.path.join(folder_path, "file2") # 读取文件:指定分隔符(根据实际情况调整,比如空格、制表符),无表头 df1 = pd.read_csv(file1_path, sep=r'\s+', header=None) df2 = pd.read_csv(file2_path, sep=r'\s+', header=None) # 重命名列方便操作 df1.columns = ["timestamp", "col2", "col3", "col4", "col5", "col6", "col7"] df2.columns = ["start_time", "end_time", "label"] # 关键:统一转为datetime类型(如果是Unix时间戳,加unit='s'或'ms') # 示例1:如果是字符串格式(如"2024-01-01 12:00:00") df1["timestamp"] = pd.to_datetime(df1["timestamp"]) df2["start_time"] = pd.to_datetime(df2["start_time"]) df2["end_time"] = pd.to_datetime(df2["end_time"]) # 示例2:如果是Unix时间戳(秒级) # df1["timestamp"] = pd.to_datetime(df1["timestamp"], unit='s') # df2["start_time"] = pd.to_datetime(df2["start_time"], unit='s') # df2["end_time"] = pd.to_datetime(df2["end_time"], unit='s') # 方法1:用apply遍历每个时间戳,匹配所有时间区间 def match_label(timestamp): # 找到所有包含该时间戳的区间,取第一个匹配的label(可根据需求调整) match = df2[(df2["start_time"] <= timestamp) & (df2["end_time"] >= timestamp)] return match["label"].iloc[0] if not match.empty else pd.NA df1["label"] = df1["timestamp"].apply(match_label) # 方法2:更高效的merge_asof(要求df1和df2按时间排序) # df1_sorted = df1.sort_values("timestamp") # df2_sorted = df2.sort_values("start_time") # df_merged = pd.merge_asof(df1_sorted, df2_sorted, left_on="timestamp", right_on="start_time", direction='backward') # # 过滤掉时间超过end_time的匹配 # df_merged["label"] = df_merged.apply(lambda x: x["label"] if x["timestamp"] <= x["end_time"] else pd.NA, axis=1) # df1 = df_merged.sort_index() # 恢复原顺序 # 添加文件夹编号列,方便后续溯源 df1["folder_id"] = folder_num all_dfs.append(df1) # 合并所有DataFrame final_df = pd.concat(all_dfs, ignore_index=True) # 查看结果 print(final_df.head())
关键注意事项
- 分隔符调整:如果你的文件是用制表符或其他分隔符,修改
sep参数(比如sep='\t') - 时间戳类型:根据实际文件的时间格式选择
pd.to_datetime的参数,比如Unix时间戳要加unit='s'或unit='ms' - 多区间匹配:如果file2有多个重叠区间,可根据需求调整
match_label函数的返回逻辑(比如返回所有匹配的label,或优先级最高的)
内容的提问来源于stack exchange,提问作者Siavash
相关产品推荐
相关产品推荐

