求Python代码:按Column3顺序重排Pandas DataFrame数据块内列1和列2
解决Pandas DataFrame分块重排的IndexError问题
你遇到的IndexError: index 0 is out of bounds for axis 0 with size 0,本质是原代码逻辑错误:处理第一个非标题行时,new_df里只有刚添加的标题行,new_df['Column 1'] == position找不到匹配项,返回空索引后强行取[0]导致越界。而且逐行插入的方式效率极低,也没抓住问题核心——应该按块处理,先建立映射再批量重排。
解决方案代码
核心思路是先把数据按标题行(含'm'或Column2为空的行)分割成独立块,每个块内建立Column3到(Column1, Column2)的映射,再按Column3的顺序生成新行,让Column1与Column3值一致,同时同步对应Column2:
import pandas as pd # 构造原始数据(也可直接读取你的数据源) data = [ ["m26:1_8.6", None, "m26:1_8.6"], ["FA8:0", 329448.0313, "FA18:1"], ["FA18:1", 4048785.5, "FA12:0"], ["FA10:0", 2232634.75, "FA10:0"], ["FA12:0", 2541154.25, "FA8:0"], ["m26:0_8.8", None, "m26:0_8.8"], ["FA8:0", 2084220.75, "FA10:0"], ["FA10:0", 5801817, "FA12:0"], ["FA2:0", 158898.5625, "FA8:0"], ["FA12:0", 3270664.25, "FA2:0"], ] df = pd.DataFrame(data, columns=["Column 1", "Column 2", "Column 3"]) # 1. 标记标题行:Column2为空 或 Column1包含'm' df["is_header"] = df["Column 2"].isna() | df["Column 1"].str.contains("m") # 2. 给每个行分配块ID(每个标题行启动一个新块) df["block_id"] = df["is_header"].cumsum() # 3. 逐个处理每个数据块 result_rows = [] for block_id in df["block_id"].unique(): block = df[df["block_id"] == block_id].copy() # 先加入当前块的标题行 header_row = block[block["is_header"]].iloc[0] result_rows.append(header_row) # 提取当前块的非标题数据行 data_rows = block[~block["is_header"]] # 建立Column3到(Column1, Column2)的映射字典 pos_mapping = data_rows.set_index("Column 3")[["Column 1", "Column 2"]].to_dict("index") # 按原数据行的Column3顺序生成重排后的行 for pos in data_rows["Column 3"]: new_row = pd.Series({ "Column 1": pos, "Column 2": pos_mapping[pos]["Column 2"], "Column 3": pos }) result_rows.append(new_row) # 4. 拼接结果并清理辅助列 new_df = pd.DataFrame(result_rows).reset_index(drop=True) print(new_df)
代码说明
- 分块标记:用
is_header标记标题行,再通过cumsum()生成块ID,把整个DataFrame拆成多个独立的数据块。 - 映射建立:每个块内,将
Column3作为键,对应行的Column1和Column2作为值,建立映射关系。 - 重排生成:遍历原数据行的
Column3值,直接用该值作为新行的Column1,同时从映射中取出对应的Column2,确保顺序和对应关系正确。
运行后输出将完全符合你的期望格式。
内容的提问来源于stack exchange,提问作者Megan Lee
相关产品推荐
相关产品推荐

