如何基于现有列的值存在情况生成含指定所有值的布尔列?
问题描述
现有如下Pandas DataFrame:
import pandas as pd df1 = pd.DataFrame(data={'col1': ['a', 'e', 'a', 'e'], 'col2': ['e', 'a', 'c', 'b'], 'col3': ['c', 'b', 'b', 'a']}, index=pd.Series([1, 2, 3, 4], name='index'))
对应的表格:
| index | col1 | col2 | col3 |
|---|---|---|---|
| 1 | a | e | c |
| 2 | e | a | b |
| 3 | a | c | b |
| 4 | e | b | a |
以及包含所有目标值的列表:
all_vals = ['a', 'b', 'c', 'd', 'e', 'f']
需要从df1生成包含all_vals中所有值对应布尔列的DataFrame,即使某个值未在df1中出现,最终期望得到如下结果:
| index | a | b | c | d | e | f |
|---|---|---|---|---|---|---|
| 1 | TRUE | FALSE | TRUE | FALSE | TRUE | FALSE |
| 2 | TRUE | TRUE | FALSE | FALSE | TRUE | FALSE |
| 3 | TRUE | TRUE | TRUE | FALSE | FALSE | FALSE |
| 4 | TRUE | TRUE | FALSE | FALSE | TRUE | FALSE |
解决方案
方法一:基于行集合的直观实现
import pandas as pd # 原始数据 df1 = pd.DataFrame(data={'col1': ['a', 'e', 'a', 'e'], 'col2': ['e', 'a', 'c', 'b'], 'col3': ['c', 'b', 'b', 'a']}, index=pd.Series([1, 2, 3, 4], name='index')) all_vals = ['a', 'b', 'c', 'd', 'e', 'f'] # 将每行的所有值转为集合,方便快速判断存在性 row_value_sets = df1.apply(set, axis=1) # 遍历目标值列表,生成对应布尔列 result_df = pd.DataFrame( {val: row_value_sets.apply(lambda x: val in x) for val in all_vals}, index=df1.index )
方法二:向量化高效实现(适合大数据量)
避免循环,通过数据重塑和交叉表实现:
import pandas as pd # 原始数据 df1 = pd.DataFrame(data={'col1': ['a', 'e', 'a', 'e'], 'col2': ['e', 'a', 'c', 'b'], 'col3': ['c', 'b', 'b', 'a']}, index=pd.Series([1, 2, 3, 4], name='index')) all_vals = ['a', 'b', 'c', 'd', 'e', 'f'] # 重塑数据格式,将多列转为"索引-值"的长表结构 melted_data = df1.reset_index().melt(id_vars='index', value_name='val') # 生成交叉表并转为布尔类型 temp_result = pd.crosstab(melted_data['index'], melted_data['val']).astype(bool) # 补充all_vals中缺失的列,并按指定顺序排列 result_df = temp_result.reindex(all_vals, axis=1, fill_value=False)
两种方法均能生成符合要求的结果,其中方法二的向量化操作在处理大规模数据时性能更优。
内容的提问来源于stack exchange,提问作者bltSandwich21
相关产品推荐
相关产品推荐

