拼接Pandas DataFrame后如何保留原有数据类型?
问题:拼接DataFrame后数据类型全部变为object
我有两个DataFrame:df和mut,其中所有DataFrame的最后一列(category)都是object类型;mut的其他列是二进制整数类型,df的其他列是浮点类型。但执行以下代码后,生成的df_scaled所有列都变成了object类型:
X = df.iloc[:,:-1].astype(int) X_scaled = pd.DataFrame(mms.fit_transform(X.values), columns=X.columns, index=X.index) y = df.iloc[:,-1:] y = df.iloc[:,-1:] df_scaled = pd.concat([X_scaled,y], axis=1) df_scaled = pd.concat([mut, df_scaled])
数据详情
df数据
pd.DataFrame({'TCGA-Y8-A8RY-01A': {'hsa-let-7a-3p': 2.082843013790784, 'hsa-let-7b-5p': 3.5720402468662744, 'hsa-let-7b-3p': 1.454168803064294, 'hsa-let-7c-5p': 3.521051767831394}, 'TCGA-Y8-A8RZ-01A': {'hsa-let-7a-3p': 2.124989064575205, 'hsa-let-7b-5p': 3.33033877243824, 'hsa-let-7b-3p': 1.795842048944672, 'hsa-let-7c-5p': 3.0978660073056066}, 'TCGA-Y8-A8S0-01A': {'hsa-let-7a-3p': 1.9381691147779496, 'hsa-let-7b-5p': 3.6787575193202096, 'hsa-let-7b-3p': 1.4976013154110766, 'hsa-let-7c-5p': 3.6586682721571377}, 'TCGA-Y8-A8S1-01A': {'hsa-let-7a-3p': 2.0583218372956287, 'hsa-let-7b-5p': 3.516734922406729, 'hsa-let-7b-3p': 1.3254164702581286, 'hsa-let-7c-5p': 3.3594612940444466}, 'category': {'hsa-let-7a-3p': 'miRNA', 'hsa-let-7b-5p': 'miRNA', 'hsa-let-7b-3p': 'miRNA', 'hsa-let-7c-5p': 'miRNA'}})
mut数据
pd.DataFrame({'TCGA-Y8-A8RY-01A': {'IGF2R': 0, 'NBEA': 0, 'KMT2D': 0, 'HERC2': 0}, 'TCGA-Y8-A8RZ-01A': {'IGF2R': 0, 'NBEA': 0, 'KMT2D': 0, 'HERC2': 0}, 'TCGA-Y8-A8S0-01A': {'IGF2R': 0, 'NBEA': 0, 'KMT2D': 0, 'HERC2': 0}, 'TCGA-Y8-A8S1-01A': {'IGF2R': 0, 'NBEA': 1, 'KMT2D': 0, 'HERC2': 0}, 'category': {'IGF2R': 'Mutation', 'NBEA': 'Mutation', 'KMT2D': 'Mutation', 'HERC2': 'Mutation'}})
原因分析
拼接后所有列变为object的核心原因是垂直拼接(axis=0)时,同一列存在数值与NaN混合存储的情况:
mut中的miRNA类列(如hsa-let-7a-3p)全为NaN,而df_scaled中这些列是浮点值;df_scaled中的突变类列(如IGF2R)全为NaN,而mut中这些列是整数。
Pandas为兼容NaN与数值的混合存储,会自动将列类型降级为object。
解决方案
方案1:拼接后按原始类型强制转换
先记录两个DataFrame各列的原始类型,拼接完成后逐一恢复类型:
# 记录各列原始数据类型 mut_dtypes = mut.dtypes df_dtypes = df.dtypes # 执行原拼接逻辑 X = df.iloc[:,:-1].astype(int) X_scaled = pd.DataFrame(mms.fit_transform(X.values), columns=X.columns, index=X.index) y = df.iloc[:,-1:] df_scaled = pd.concat([X_scaled, y], axis=1) df_scaled = pd.concat([mut, df_scaled]) # 重新设置各列数据类型 for col in df_scaled.columns: if col in mut_dtypes: df_scaled[col] = df_scaled[col].astype(mut_dtypes[col]) if col in df_dtypes: df_scaled[col] = df_scaled[col].astype(df_dtypes[col])
方案2:填充NaN为对应类型默认值后再拼接
针对不同类型的列,将NaN填充为对应类型的默认值,避免混合类型触发类型降级:
# 处理df_scaled:给突变类列填充0(整数类型) mut_cols = mut.columns.difference(df.columns) df_scaled[mut_cols] = df_scaled[mut_cols].fillna(0).astype(int) # 处理mut:给miRNA类列填充0.0(浮点类型) miRNA_cols = df.columns.difference(mut.columns) mut[miRNA_cols] = mut[miRNA_cols].fillna(0.0).astype(float) # 执行拼接 df_scaled = pd.concat([mut, df_scaled])
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

