如何对多份pandas DataFrame中取值不全的列进行独热编码?
解决独热编码列不统一的方案
核心思路是先收集所有待编码列的全量可能取值,再基于这个全量集合对每个单独的DataFrame做编码,确保所有编码后的DataFrame拥有完全一致的列。
步骤1:收集全量类别(内存友好)
不用合并整个DataFrame,只提取每个待编码列的唯一值,内存占用极低:
# 定义需要独热编码的列(比如球队、事件类型) encode_cols = ["team", "event_type"] # 初始化字典存储每个列的全量可能取值 full_categories = {col: set() for col in encode_cols} # 遍历所有赛季的DataFrame,收集每个列的所有唯一值 for df in your_dataframe_list: # your_dataframe_list是你的10个DataFrame组成的列表 for col in encode_cols: # 确保列类型一致(比如都是字符串),避免遗漏取值 col_values = df[col].astype(str).unique() full_categories[col].update(col_values) # 把集合转成列表,方便后续编码使用 for col in encode_cols: full_categories[col] = list(full_categories[col])
步骤2:对单个DataFrame统一编码
方法一:用pandas自带的get_dummies
指定categories参数为全量取值,缺失的取值会自动生成全0的列:
def encode_single_df(df, encode_cols, full_categories): # 逐个列生成独热编码 dummy_dfs = [] for col in encode_cols: # 指定categories确保列统一,dtype=int节省内存 dummy = pd.get_dummies(df[col], prefix=col, categories=full_categories[col], dtype=int) dummy_dfs.append(dummy) # 合并原数据和编码列,删掉原编码列(可选) encoded_df = pd.concat([df] + dummy_dfs, axis=1).drop(encode_cols, axis=1) return encoded_df # 批量处理所有DataFrame encoded_dataframes = [encode_single_df(df, encode_cols, full_categories) for df in your_dataframe_list]
方法二:用sklearn的OneHotEncoder
适合后续要衔接sklearn模型的场景,同样基于全量类别生成编码:
from sklearn.preprocessing import OneHotEncoder # 为每个列初始化编码器,指定全量类别 encoders = {} for col in encode_cols: # sparse_output=False直接生成密集矩阵,dtype=int节省内存 enc = OneHotEncoder(categories=[full_categories[col]], sparse_output=False, dtype=int) encoders[col] = enc def encode_single_df_sklearn(df, encode_cols, encoders): encoded_parts = [] for col in encode_cols: # 转换数据(需转成二维数组) encoded_values = encoders[col].transform(df[col].values.reshape(-1, 1)) # 生成编码列的名称 col_names = [f"{col}_{cat}" for cat in encoders[col].categories_[0]] # 转成DataFrame并保留原索引 encoded_df = pd.DataFrame(encoded_values, columns=col_names, index=df.index) encoded_parts.append(encoded_df) # 合并原数据和编码列 encoded_full = pd.concat([df] + encoded_parts, axis=1).drop(encode_cols, axis=1) return encoded_full # 批量处理 encoded_dataframes_sklearn = [encode_single_df_sklearn(df, encode_cols, encoders) for df in your_dataframe_list]
关键注意点
- 确保待编码列的数据类型一致(比如所有DataFrame的
team列都是字符串),否则可能导致取值收集不全。 - 如果数据中有NaN值,可以选择将其作为一个独立类别(收集时会自动包含),或者提前填充后再处理。
- 编码后的列顺序可能需要统一?可以在生成编码后用
reindex指定固定列顺序,确保所有DataFrame列顺序完全一致:# 获取所有编码后的列名(取第一个编码后的DataFrame的列名即可) all_cols = encoded_dataframes[0].columns.tolist() # 统一所有DataFrame的列顺序 encoded_dataframes = [df.reindex(all_cols, axis=1) for df in encoded_dataframes]
内容的提问来源于stack exchange,提问作者namor129
相关产品推荐
相关产品推荐

