使用Pandas选定列结合函数生成矩阵时遇ValueError问题求助
解决pd.crosstab循环生成结果矩阵时的ValueError问题
问题背景
我想要基于DataFrame列对的交叉表计算结果生成一个矩阵,具体是遍历所有列对,用pd.crosstab生成交叉表后传入自定义函数my_function(该函数能返回标量结果),最终把所有结果填充到一个和列数同维度的零矩阵里。我用cols_index存储了要操作的DataFrame列索引,写了如下代码:
cols_index # 存储DataFrame列索引的列表,无问题 res_matrix = np.zeros([len(cols_index),len(cols_index)]) # 维度与列数一致的零矩阵 for i in cols_index: for j in cols_index: confusion_matrix = pd.crosstab(df.columns.get_values()[i], df.columns.get_values()[j]) # df.columns.get_values()[位置] result = my_function(confusion_matrix) # 返回标量 res_matrix[i, j] = result return res_matrix
但运行时碰到了这个错误:
ValueError: If using all scalar values, you must pass an index
奇怪的是,直接单独对两列调用时完全正常:
confusion_matrix = pd.crosstab(df['colA'], df['colB']) result = my_function(confusion_matrix) # 返回0.29999,无问题
错误原因分析
你的代码里有两个关键问题:
- 列引用错误:
cols_index是列名的列表(比如['colA','colB']),循环里的i是列名字符串,而df.columns.get_values()[i]是试图用字符串去索引列名数组,这会导致你拿到的不是DataFrame的列数据,而是单个字符串(列名)——相当于你给pd.crosstab传了两个标量值,这就触发了报错。 - 矩阵索引不匹配:
res_matrix是numpy数组,只能用整数索引,但你试图用列名字符串i,j去赋值res_matrix[i,j],这同样会出错。
解决方案
修正后的代码需要同时解决这两个问题,用enumerate获取列名的整数位置,同时直接引用DataFrame的列:
import numpy as np import pandas as pd cols_index = ['colA', 'colB', 'colC'] # 示例列名列表 res_matrix = np.zeros([len(cols_index), len(cols_index)]) # 用enumerate获取每个列名的位置索引和列名本身 for row_idx, col_i in enumerate(cols_index): for col_idx, col_j in enumerate(cols_index): # 直接用df[col_i]和df[col_j]获取列数据,生成交叉表 confusion_matrix = pd.crosstab(df[col_i], df[col_j]) result = my_function(confusion_matrix) # 用整数索引给矩阵赋值 res_matrix[row_idx, col_idx] = result return res_matrix
关键改动说明
- 用
enumerate(cols_index)拿到每个列名对应的整数位置(row_idx和col_idx),这样就能正确给numpy矩阵res_matrix赋值。 - 直接通过
df[col_i]和df[col_j]获取列数据,传给pd.crosstab,这和你单独调用时的逻辑一致,不会再传标量值。
这样修改后,代码就能正常生成你需要的结果矩阵了。
内容的提问来源于stack exchange,提问作者LucieCBurgess
相关产品推荐
相关产品推荐

