如何将融合转置后作为索引的食品分类信息拆分并转换为DataFrame常规列
如何将融合转置后作为索引的食品分类信息拆分并转换为DataFrame常规列
看起来你已经摸到门道啦,只是最后处理索引拆分的时候有点小语法问题,而且咱们还可以优化前期的代码逻辑,避免把分类信息塞进列名里给自己添麻烦。我来一步步帮你解决:
一、先修复当前代码的索引拆分问题
你最后一行代码里的final_df.[0]是语法错误——转置后的final_df,那些带分号的分类信息其实是它的索引,不是列。咱们直接对索引进行拆分就好,还要记得去掉字符串里多余的空格:
# 转置后的final_df,索引是带分号的字符串,拆分索引到新列 final_df[['Type', 'Subtype', 'Sub-subtype', 'N']] = final_df.index.to_series().apply( lambda x: pd.Series([s.strip() for s in str(x).split(";")]) ) # 把索引里的"the_meat"改成你想要的"Meat"格式 final_df['Type'] = final_df['Type'].str.replace('the_meat', 'Meat') # 可选:如果不需要原来的索引了,可以删掉它 final_df = final_df.reset_index(drop=True)
这样就能直接得到你想要的Type/Subtype/Sub-subtype/N这几列啦。
二、优化前期代码逻辑(从根源避免麻烦)
其实你一开始把分类信息塞进列名的做法,会让后续处理变复杂。咱们可以提前给每个临时DataFrame加上分类列,最后再合并转成宽格式,逻辑更清晰:
x_axel = [] amrS = uag.set_index('AMRs') for i in x: # x是食品大类:meat, fish, vegetables... y = ft[i].dropna().tolist() pattern = '|'.join(map(re.escape, y)) typeF = df[df['Isolation source'].str.contains(pattern, case=False, na=False)] # 处理大类数据,新增分类列 df_type = pd.melt(typeF, id_vars=['Isolation source'], value_name=i)[i].value_counts().reset_index() df_type.columns = ['AMRs', 'Count'] df_type['Type'] = i.replace('the_', '') # 直接把the_meat改成Meat df_type['Subtype'] = '' df_type['Sub-subtype'] = '' df_type['N'] = typeF.shape[0] x_axel.append(df_type) for j in y: # 处理子类数据 subtypeF = df[df['Isolation source'].str.contains(j, case=False, na=False)] df_subtype = pd.melt(subtypeF, id_vars=['Isolation source'], value_name=i)[i].value_counts().reset_index() df_subtype.columns = ['AMRs', 'Count'] df_subtype['Type'] = i.replace('the_', '') df_subtype['Subtype'] = j df_subtype['Sub-subtype'] = '' df_subtype['N'] = subtypeF.shape[0] x_axel.append(df_subtype) subsubTL = list(set(subtypeF['Isolation source'].to_list())) for k in subsubTL: # 处理具体食品数据 # 这里用==替代contains,避免匹配到相似的字符串,更严谨 subsubtypeF = df[df['Isolation source'] == k] df_subsubtype = pd.melt(subsubtypeF, id_vars=['Isolation source'], value_name=i)[i].value_counts().reset_index() df_subsubtype.columns = ['AMRs', 'Count'] df_subsubtype['Type'] = i.replace('the_', '') df_subsubtype['Subtype'] = j df_subsubtype['Sub-subtype'] = k df_subsubtype['N'] = subsubtypeF.shape[0] x_axel.append(df_subsubtype) # 合并所有临时数据,补全缺失的AMR基因(填充0) combined_df = pd.concat(x_axel, ignore_index=True) full_amr = pd.DataFrame({'AMRs': uag['AMRs']}) combined_df = pd.merge(full_amr, combined_df, on='AMRs', how='left').fillna(0) # 转成你想要的宽格式:行是分类信息,列是AMR基因 final_df = combined_df.pivot_table( index=['Type', 'Subtype', 'Sub-subtype', 'N'], columns='AMRs', values='Count', fill_value=0, aggfunc='sum' ).reset_index()
这样处理完,直接就能得到和你预期完全一致的表格,不需要再折腾索引拆分的步骤,后续维护也更方便。
几个小细节提醒
- 匹配具体食品时,用
==替代contains,能避免误匹配(比如不会把"chicken salad"和"chicken nugget"混在一起) - 提前处理
the_前缀,避免后续再修改字符串 - 用
pivot_table生成宽格式,比循环join多个DataFrame更高效
备注:内容来源于stack exchange,提问作者Dragoran21
相关产品推荐
相关产品推荐

