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

如何用Pandas将服务器Oracle客户端表转为指定宽表格式?

解决Pandas Crosstab复合索引转普通列的问题

问题背景

我们有一张非规范化的服务器表,包含服务器主机名、IP(主机名与IP为一对一关系),以及安装在服务器上的多个Oracle客户端版本。原始数据构造及输出如下:

import pandas as pd
from tabulate import tabulate

col_server      =   ['server_A','server_A','server_A']
col_ip          =   ['ip_A'    , 'ip_A'   , 'ip_A'   ]
col_ora_client  =   ['11'      ,'12'      ,'19'      ]
df              =   pd.DataFrame(data=list(zip(col_server,col_ip,col_ora_client)) , columns=["server","ip","ora_client"])
print(tabulate(df, headers='keys', tablefmt='psql'))

运行输出:

+----+----------+------+--------------+
|    | server   | ip   |   ora_client |
|----+----------+------+--------------|
|  0 | server_A | ip_A |           11 |
|  1 | server_A | ip_A |           12 |
|  2 | server_A | ip_A |           19 |
+----+----------+------+--------------+

期望格式

需要将数据转换为宽表,每个Oracle客户端版本作为独立列,存在则标记为1:

+----------+------+----+----+----+
|  server  |  ip  | 11 | 12 | 19 |
+----------+------+----+----+----+
| server_A | ip_A |  1 |  1 |  1 |
+----------+------+----+----+----+

尝试的问题

使用pd.crosstab透视后,server和ip以元组形式作为复合索引,不符合需求:

df_b = pd.crosstab([df['server'], df['ip']], df['ora_client'])
print(tabulate(df_b, headers='keys', tablefmt='psql'))

输出:

+----------------------+------+------+------+
|                      |   11 |   12 |   19 |
|----------------------+------+------+------|
| ('server_A', 'ip_A') |    1 |    1 |    1 |
+----------------------+------+------+------+

解决方案

方法1:用reset_index()还原索引列

在crosstab结果上调用reset_index(),将复合索引转为普通列,再通过tabulate参数隐藏默认索引:

df_b = pd.crosstab([df['server'], df['ip']], df['ora_client']).reset_index()
print(tabulate(df_b, headers='keys', tablefmt='psql', showindex=False))

输出:

+----------+------+------+------+------+
| server   | ip   |   11 |   12 |   19 |
+----------+------+------+------+------|
| server_A | ip_A |    1 |    1 |    1 |
+----------+------+------+------+------+

方法2:使用pivot_table替代crosstab

直接通过pivot_table指定行、列和统计逻辑,同样能得到目标格式:

df_b = df.pivot_table(index=['server', 'ip'], columns='ora_client', aggfunc='size', fill_value=0).reset_index()
print(tabulate(df_b, headers='keys', tablefmt='psql', showindex=False))

输出结果与方法1完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:25:35