如何一次性将Pandas DataFrame列值转为基于唯一值数量的数值表示(含自定义种子)
批量转换Pandas DataFrame多列为数值映射(空值转-1,支持自定义种子)
我来帮你搞定这个数据转换需求,下面分基础连续整数映射和自定义种子函数映射两种方案详细说明,完全匹配你给出的示例要求。
一、基础实现:默认连续整数映射
这个版本会把每列的唯一非空值按出现顺序映射为1、2、3...这样的连续正整数,所有空值(包括空字符串'')统一替换为-1,和你给出的data1示例完全一致。
步骤1:构造示例DataFrame
首先把测试数据转换成Pandas DataFrame:
import pandas as pd data = { 'Col1': ['G1', 'G2', 'G9','G4','G6',''], 'Col2': ['H2', 'H1', 'H9','H9','',''], 'Col3': ['D2', 'D1', 'D9','','',''], 'Col4': ['GHD2', 'GHD1', 'GHD9','GHD9','GDH11','GDH13'] } df = pd.DataFrame(data)
步骤2:编写批量转换函数
先写一个处理单列的函数,再用apply批量应用到所有列:
def map_col_to_numeric(col): # 先把空字符串转成Pandas标准空值pd.NA,方便统一处理 col_clean = col.replace('', pd.NA) # 使用factorize生成初始映射,na_sentinel指定空值的临时标记为-1 mapped, _ = pd.factorize(col_clean, na_sentinel=-1) # 把非空值的映射从0开始改成1开始,空值保持-1 return [val + 1 if val != -1 else -1 for val in mapped] # 应用到所有列,得到转换后的DataFrame df_converted = df.apply(map_col_to_numeric)
运行后查看df_converted,就是你要的结果:
Col1 Col2 Col3 Col4 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 3 -1 3 4 5 -1 -1 4 5 -1 -1 -1 5
二、扩展实现:支持自定义种子函数
如果需要用你提到的weighted_value这类自定义函数生成种子值来决定数值体系,我们可以调整逻辑,先给每个唯一值分配自定义种子,再做映射。
步骤1:定义自定义种子函数
这里模拟一个weighted_value函数(你可以替换成自己的业务逻辑),比如根据字符串长度生成种子:
def weighted_value(unique_val): # 示例:根据字符串长度返回种子值,你可以改成自己的规则 return len(unique_val) * 2
步骤2:编写支持自定义映射的转换函数
def map_col_with_custom_seed(col, seed_func): # 统一处理空字符串为pd.NA col_clean = col.replace('', pd.NA) # 获取列中的非空唯一值 unique_vals = col_clean.dropna().unique() # 用自定义函数生成{唯一值: 种子值}的映射字典 value_map = {val: seed_func(val) for val in unique_vals} # 执行映射,空值默认返回-1 return col_clean.map(lambda x: value_map.get(x, -1)) # 应用到所有列,传入自定义种子函数 df_custom = df.apply(map_col_with_custom_seed, seed_func=weighted_value)
运行后,df_custom的数值就会按照weighted_value的规则生成,比如Col4里的GHD2长度为4,对应种子值8;GDH11长度为5,对应种子值10。
关键细节提示
- 空值统一处理:把空字符串转成
pd.NA是为了避免factorize或者map把空字符串当成普通唯一值,确保所有空内容都映射为-1。 - 批量效率:用
DataFrame.apply()比手动循环每列更高效,尤其是数据量大的时候。 - 灵活性:自定义种子函数可以是任何逻辑——比如从外部配置字典取值、计算权重、关联其他数据等,只需要保证函数接收唯一值参数并返回对应的数值即可。
内容的提问来源于stack exchange,提问作者user2277675
相关产品推荐
相关产品推荐

