You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Polars识别问卷数据中缺失的答案编码?

更符合Polars风格的问卷答案缺失项检查方案

问题背景

我有一个存储问卷问题答案编码的Polars DataFrame,想要确认所有预期答案是否都存在于该DataFrame中,若存在缺失则找出具体的缺失项。我已经写出了可行代码,但想了解有没有更符合Polars风格的实现方式?

原实现代码

import polars as pl

fields = {}
fields['q1'] = [f'Q1A{i}' for i in range(1,12)]
fields['q2'] = [f'Q2A{i}' for i in range(1,3)]
fields['q3'] = [f'Q3A{i}' for i in range(1,8)]
fields['q4'] = [f'Q4A{i}' for i in range(1,4)]
df = pl.DataFrame({'id': [1,2,3,4,5],
                   'q1': ['Q1A1,Q1A2','Q1A6','Q1A7,Q1A9','Q1A11','Q1A5,Q1A3'],
                   'q2': ['Q2A1','','Q2A2','Q2A1','Q2A1'],
                   'q3': ['Q3A1','Q3A3','Q3A2,Q3A5','Q3A6','Q3A7'],
                   'q4': ['Q4A1,Q4A3','Q4A1','','Q4A1','Q4A1'],
                   })
for f in df.columns:
    if f.startswith('q'):
        print(pl.DataFrame(fields[f], schema={f: pl.String})
                .join(df.select(pl.col(f).str.split(by=",").explode().unique().str.replace(r'(\: .*)',''))
                        .filter(pl.col(f) != pl.lit('')),
                      on = f,
                      how = 'anti'
                      )
                .select(pl.lit(f),
                        pl.len(),
                        pl.col(f).str.join(', ').alias('missing')
                       )
                .rows()
              )

原运行结果

[('q1', 3, 'Q1A4, Q1A8, Q1A10')]
[('q2', 0, '')]
[('q3', 1, 'Q3A4')]
[('q4', 1, 'Q4A2')]

优化后的Polars风格实现

下面的实现完全利用Polars的向量化、批量处理特性,避免Python循环,代码更简洁规整,也更符合Polars的设计理念:

import polars as pl

# 定义预期答案映射
fields = {
    'q1': [f'Q1A{i}' for i in range(1,12)],
    'q2': [f'Q2A{i}' for i in range(1,3)],
    'q3': [f'Q3A{i}' for i in range(1,8)],
    'q4': [f'Q4A{i}' for i in range(1,4)]
}

# 将预期答案转换为结构化DataFrame,统一管理问题和对应答案
expected_df = pl.concat(
    [pl.DataFrame({'question': q, 'answer': ans}) for q, ans in fields.items()]
)

# 处理原始数据:拆分多值答案、去重、过滤空值,转长表格式
existing_answers = df.select(
    pl.col('^q.*$').str.split(',').explode().unique()
).melt(
    variable_name='question', value_name='answer'
).filter(pl.col('answer') != '')

# 通过anti join找出所有缺失的答案,按问题聚合统计结果
missing_df = expected_df.join(
    existing_answers,
    on=['question', 'answer'],
    how='anti'
).group_by('question').agg(
    pl.len().alias('missing_count'),
    pl.col('answer').str.join(', ').alias('missing_items')
).sort('question')

# 左连接填充无缺失的问题,保证结果包含所有预期问题
final_result = pl.DataFrame({'question': list(fields.keys())}).join(
    missing_df, on='question', how='left'
).fill_null({'missing_count': 0, 'missing_items': ''})

print(final_result)

优化后运行结果

shape: (4, 3)
┌──────────┬──────────────┬──────────────────────┐
│ question ┆ missing_count ┆ missing_items        │
│ ---      ┆ ---          ┆ ---                  │
│ str      ┆ i64          ┆ str                  │
╞══════════╪══════════════╪══════════════════════╡
│ q1       ┆ 3            ┆ Q1A4, Q1A8, Q1A10    │
│ q2       ┆ 0            ┆                      │
│ q3       ┆ 1            ┆ Q3A4                 │
│ q4       ┆ 1            ┆ Q4A2                 │
└──────────┴──────────────┴──────────────────────┘

优化说明

  • 去掉Python循环:全程用Polars内置操作处理,充分发挥Polars的向量化计算优势,性能更优
  • 结构化管理预期答案:将预期答案转换为DataFrame,统一处理所有问题,代码扩展性更强
  • 长表格式适配:用melt将宽表转长表,简化后续的join和聚合逻辑,符合Polars的结构化数据处理思路
  • 结果规整性:通过左连接填充无缺失的问题,确保结果包含所有预期问题,输出格式更统一

内容的提问来源于stack exchange,提问作者lmocsi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 17:53:10