如何迭代生成多个交叉表DataFrame?解决ValueError报错
批量生成交叉表DataFrame的报错解决
问题背景
给定样本数据集:
ID 1 2 3 X Y Z 0 1 2 1 2 3 3 4 1 2 1 3 1 4 3 4 2 3 2 2 1 2 4 3 3 4 3 2 1 2 3 3 4 5 1 2 2 1 3 2 5 6 2 3 2 4 4 2
需要批量生成pd.crosstab交叉表,其中列1/2/3对应企业类型(1=大型企业,2=小型企业,3=非营利组织),列X/Y/Z为调查问题。手动执行单个交叉表可正常运行:
cross1 = pd.crosstab(sample["1"], sample["X"]) print(cross1)
输出结果:
X 1 2 3 4 1 1 1 0 0 1 2 0 1 1 1 3 0 1 0 0
尝试用循环批量生成时,代码触发报错:
demo_questions = ['1', '2', '3'] survey_questions = ['X', 'Y', 'Z'] for d, s in [demo_questions, survey_questions]: cross[d] = pd.crosstab(sample[d], sample[s])
报错信息:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[37], line 1 ----> 1 for d, s in [demo_questions, survey_questions]: 2 cross[d] = pd.crosstab(sample[d], sample[s]) ValueError: too many values to unpack (expected 2)
报错原因
循环的迭代对象是[demo_questions, survey_questions],这是一个包含两个列表的容器。第一次循环时,会把长度为3的demo_questions列表赋值给d, s,但d, s仅期望接收2个值,因此触发"too many values to unpack"错误。
解决方案
根据需求分两种场景实现批量生成:
场景1:生成所有企业类型与调查问题的组合交叉表(共9个)
使用itertools.product生成两个列表的笛卡尔积,遍历所有可能的组合:
import pandas as pd from itertools import product # 用字典存储所有交叉表,便于管理 cross_tables = {} demo_questions = ['1', '2', '3'] survey_questions = ['X', 'Y', 'Z'] # 遍历所有企业类型+调查问题的组合 for demo_col, survey_col in product(demo_questions, survey_questions): # 用列名组合作为字典键,比如"1_X"、"2_Y" cross_key = f"{demo_col}_{survey_col}" cross_tables[cross_key] = pd.crosstab(sample[demo_col], sample[survey_col]) # 示例:查看企业类型1与调查问题X的交叉表 print(cross_tables["1_X"])
场景2:生成企业类型与调查问题一一对应的交叉表(共3个:1-X、2-Y、3-Z)
使用zip()函数将两个列表按索引配对遍历:
import pandas as pd cross_tables = {} demo_questions = ['1', '2', '3'] survey_questions = ['X', 'Y', 'Z'] # 按索引一一配对遍历 for demo_col, survey_col in zip(demo_questions, survey_questions): # 自定义变量名作为字典键,比如"cross1"、"cross2" cross_key = f"cross{demo_col}" cross_tables[cross_key] = pd.crosstab(sample[demo_col], sample[survey_col]) # 示例:查看cross1(即企业类型1与调查问题X的交叉表) print(cross_tables["cross1"])
可选:生成独立变量(不推荐)
如果确实需要创建cross1、cross2这类独立变量,可通过globals()动态赋值,但字典存储的方式更安全规范:
for demo_col, survey_col in zip(demo_questions, survey_questions): var_name = f"cross{demo_col}" globals()[var_name] = pd.crosstab(sample[demo_col], sample[survey_col]) # 直接调用独立变量 print(cross1)
内容的提问来源于stack exchange,提问作者cMX5
相关产品推荐
相关产品推荐

