如何将DataFrame单元格数值转为列并标记出现情况?
实现DataFrame数值存在性标记的最优方法
需求说明
原DataFrame包含Location1、Location2、Location3三列数值,需新增is_1至is_6列,每行的is_n标记该行是否在任意Location列中出现过数值n,出现则标记为1,否则为0。
最优实现方法
方法一:向量化操作(适合大数据集,效率优先)
通过melt将宽表转长表,结合crosstab统计每行数值出现情况,最后合并回原表,全程使用pandas向量化API,避免循环,性能更优。
import pandas as pd # 构造原DataFrame df = pd.DataFrame({ 'Location1': [1, 2, 3, 3], 'Location2': [2, 5, 6, 1], 'Location3': [3, 1, 2, 4] }) # 保留行索引用于后续合并 df_with_idx = df.reset_index() # 熔化为长格式,保留行索引关联 melted = df_with_idx.melt(id_vars='index', value_vars=['Location1', 'Location2', 'Location3']) # 生成交叉表,统计每行各数值出现次数 cross_table = pd.crosstab(melted['index'], melted['value']) # 将次数转为1/0标记(只要出现过即为1) binary_markers = cross_table.applymap(lambda x: 1 if x > 0 else 0) # 重命名列名为is_*格式 binary_markers.columns = [f'is_{col}' for col in binary_markers.columns] # 合并回原DataFrame final_df = df.join(binary_markers) print(final_df)
方法二:行级遍历实现(代码简洁,适合小数据集)
通过apply遍历每行,针对所有唯一数值生成标记列,代码逻辑直观易懂,适合快速验证需求。
import pandas as pd df = pd.DataFrame({ 'Location1': [1, 2, 3, 3], 'Location2': [2, 5, 6, 1], 'Location3': [3, 1, 2, 4] }) # 获取所有唯一数值并排序 unique_values = sorted(df.stack().unique()) # 对每行生成对应的is_*标记列 marker_cols = df.apply( lambda row: pd.Series( [1 if val in row.values else 0 for val in unique_values], index=[f'is_{v}' for v in unique_values] ), axis=1 ) # 合并原表与标记列 final_df = pd.concat([df, marker_cols], axis=1) print(final_df)
方法对比
- 方法一:依赖pandas向量化操作,无显式循环,处理十万级以上数据时性能优势明显。
- 方法二:代码逻辑直观,易理解,但行级
apply本质是循环,大数据集下效率较低。
内容的提问来源于stack exchange,提问作者essamSALAH
相关产品推荐
相关产品推荐

