Python Pandas 中的交叉表分析

Cross Tab Analysis in Python Pandas

所以我正在创建一个网页,用户可以 运行 对导入的数据文件的选定行和列进行交叉表分析。我正在将文件转换为 pandas 数据帧,然后使用 pandas.crosstab 对其进行处理。但是,因为交叉表输出 "stacked" 或多索引 table,我必须对其进行旋转,以便更易于使用和输出回网页。我一直在尝试使用 pandas 具有的枢轴函数,但找不到一个好的动态示例。

Here's 我一直在查看 pandas 中的一些旋转文档,但它没有显示列和行标签是动态的示例。

现在我的交叉表函数是:

cross_tab = pd.crosstab([dataframe[row] for row in selected_rows], [dataframe[col] for col in selected_columns], margins=False, dropna=False)

并说我的数据框是...

+-----+------------+-------+
|id   |credit card |gender |
+-----+------------+-------+
|1    |chase       |F      |
|2    |visa        |M      |
|3    |chase       |M      |
|4    |chase       |F      |
|5    |mastercard  |M      |
|6    |visa        |M      |
|7    |mastercard  |F      |
|8    |mastercard  |M      |
|9    |mastercard  |M      |
|10   |visa        |M      |
+-----+------------+-------+

如果我 运行 它的选定行是 ['id'] 和列 ['credit card', 'gender'] 它看起来像...

+------------+----------------+-----------+-------+
|credit_card |americanexpress |mastercard |visa   |
+------------+----------------+-----------+-------+
|gender      | F  M           | F  M      | F  M  |
+------------+----------------+-----------+-------+
|id          |                |           |       |
|1           | 1  0           | 0  0      | 0  0  |
|2           | 0  0           | 0  0      | 0  1  |
|3           | 0  1           | 0  0      | 0  0  |
|4           | 1  0           | 0  0      | 0  0  | 
|5           | 0  0           | 0  1      | 0  0  |  
|6           | 0  0           | 0  0      | 0  1  |   
|7           | 0  0           | 1  0      | 0  0  | 
|8           | 0  0           | 0  1      | 0  0  |   
|9           | 0  0           | 0  1      | 0  0  |  
|10          | 0  0           | 0  0      | 0  1  |  
+------------+----------------+-----------+-------+

我在旋转时遇到问题,或者只是 "unstacking" 要存储的交叉表,然后输出到网页。我一直在尝试使用 pandas.pivot 来执行此操作,但我从中收到错误。我很确定这是更多的用户错误,并且只想看一个示例,说明如果列名和行名是动态的,如何完成。有人可以使用 pandas 枢轴将其转换为枢轴 table 来组合一个动态示例吗?如果有另一种不使用 pandas 的更简单的方法,我也很乐意看看。

很长一段时间后,我想出了一种方法,既可以将我需要的 CrossTab 输出到网页,又可以将它无误地存储为 pyarrow 格式。 .reset_index(),正如评论中提到的@user32185,确实有帮助。但是,如果在 MultiIndex Dataframe 上使用,它会使它变平,这不会按照我想要的方式输出。

我是如何处理它的,方法是使用 pandas 中的 dataframe.to_html() 命令并将其存储起来,以便稍后拍摄到 html 页面。 to_html() 在 html 中创建一个 table 的字符串,并保留 CrossTab 输出的确切方式。之后,我开始存储实际的数据框以进行母校计算。

开始时,我会检查 CrossTab 是否为 MultiIndex,如果是,我会去掉列和索引标题并将它们替换为 col1, col2, col3, .. , colx,同样替换为 row1, row2, row3, .. , rowx.之后,我存储了新的 "re-indexed" 数据帧,并以 json 格式存储了剥离的 headers 。这就是为什么当我拉出数据框时,我可以重建 MultiIndex 标题并将它们附加回数据框。这是我用来剥离的代码,以防有兴趣的人。

对于列标题,ct 是我的 CrossTab 数据框...

multi_index_levels = []
for i in range(len(ct.columns.levels)):
    multi_index_levels.append(ct.columns.get_level_values(i))
multi_index_level_tuples = list(zip(*multi_index_levels))
multi_index_level_names = ct.columns.names
flat_index = pd.MultiIndex.from_arrays([['col%s'%i for i in range(len(ct.columns))]])
ct.columns = flat_index

为了重建它,我刚刚保存了 multi_index_level_tuplesmulti_index_level_names,然后使用 MultiIndex pandas 提供的方法将标题再次拼凑起来,就像这样...

new_multi_index = pd.MultiIndex.from_tuples(multi_index_level_tuples, names=multi_index_level_names)

最后像这样附上列和索引标题...

ct.columns = new_multi_index

我能够从 here, the pandas crosstab docs, and here、pandas 数据框文档中获取大部分信息。这是一种有点复杂和蛮力的解决方案,但它对我有用。希望以后能对其他人有所帮助。