Pandas:如何处理层级索引高层级关联的重复数据?
Pandas 数据规范化问题解答
数据背景
当前有一个通过以下命令读取的Pandas DataFrame:
df = pd.read_csv(PATH, index_col=["subject_code", "datapoint"])
其结构如下(实际数据量更大):
dob name x y subject_code datapoint subject1 0 2000 foo 1.0130617046645218 -0.9197554534168588 1 2000 foo 1.6268826597606547 0.9235889343439213 2 2000 foo -0.27934495719523383 -0.7649336229271105 subject2 3 1980 bar 0.799986663648364 0.17376727917253385 4 1980 bar 0.05939596855122923 1.6401662246395807 5 1980 bar -0.6496807099005506 -0.9591735410133281 6 1980 bar -0.6953680580655669 -0.15390936342856965
其中dob、name这类subject级属性在每行重复存储,不符合数据规范化最佳实践。
问题1:能否在同一张表中将dob和name与高层级索引subject_code关联,避免重复存储?
可以通过构建包含subject_code、dob、name的多层索引实现同表内无重复存储。Pandas在显示多层索引时会自动合并重复的上层索引值,使用高效存储格式(如Parquet、HDF5)时,索引的冗余会被优化,不会重复存储相同的dob和name值。
实现代码:
# 重置索引后重新构建多层索引 df = df.reset_index() df = df.set_index(["subject_code", "dob", "name", "datapoint"]) # 查看优化后的显示效果(上层重复索引会被省略) print(df)
如果不想大幅调整索引结构,也可以通过分组关联的方式,让dob和name仅为每个subject_code保留唯一值(内存中仍会有重复,但显示更简洁):
# 保留观测列,关联唯一的subject属性 df_optimized = df[["x", "y"]].join(df.groupby("subject_code")[["dob", "name"]].first())
问题2:将subject_code、dob和name提取到独立的小型表中的最优方法是什么?
最优方法是直接按subject_code分组,提取每组的唯一dob和name值,比先筛选列再去重更高效,尤其适合大数据量场景:
方法1:直接分组取唯一值(推荐)
# 提取独立的subject信息表 subject_df = df.groupby("subject_code")[["dob", "name"]].first()
方法2:基于你已完成的筛选步骤优化
如果你已经筛选出了subject级列(即每个subject_code下值唯一的列),只需去重即可:
# 你已完成的筛选步骤 subject_cols = df.groupby("subject_code").nunique().max() == 1 subject_cols = subject_cols.index[subject_cols] # 去重得到独立的subject表 subject_df = df[subject_cols].reset_index().drop_duplicates(subset="subject_code").set_index("subject_code")
提取完成后,可以清理原数据,仅保留观测级数据:
# 移除原表中的重复属性列 df_clean = df.drop(columns=["dob", "name"])
内容的提问来源于stack exchange,提问作者S. Dauncey
相关产品推荐
相关产品推荐

