在Pandas中按日期创建透视表并计算带宽使用率时报错,如何解决?
问题描述
我有如下DataFrame:
Node Interface Speed Band_In carrier Date Server1 wan1 100 80 ATT 2024-06-01 Server1 wan2 100 60 Sprint 2024-06-01 Server1 wan3 100 96 Verizon 2024-06-01 Server2 wan1 100 80 ATT 2024-06-01 Server2 wan2 100 60 ATT 2024-06-01 Server2 wan3 100 96 ATT 2024-06-01 Server3 wan1 100 80 ATT 2024-06-01 Server3 wan2 100 60 ATT 2024-06-01 Server3 wan3 100 96 ATT 2024-06-01 Server4 wan1 100 80 ATT 2024-06-01 Server4 wan2 100 60 ATT 2024-06-01 Server5 Int3 100 96 Verizon 2024-06-01 Server1 wan1 100 30 ATT 2024-06-10 Server1 wan2 100 30 Sprint 2024-06-10 Server1 wan3 100 15 Verizon 2024-06-10 Server2 wan1 100 80 ATT 2024-06-10 Server2 wan2 100 60 ATT 2024-06-10 Server2 wan3 100 96 ATT 2024-06-10 Server3 wan1 100 80 ATT 2024-06-10 Server3 wan2 100 60 ATT 2024-06-10 Server3 wan3 100 96 ATT 2024-06-10 Server4 wan1 100 80 ATT 2024-06-10 Server4 wan2 100 60 ATT 2024-06-10 Server5 Int3 100 96 Verizon 2024-06-10
需求是:
- 将每个唯一日期转为单独列
- 按Node、Interface、carrier和Date计算接口使用率:
(Band_In/Speed)*100 - 日期格式改为“月份名称-日期”(如June-01、June-10)
- 最终结果示例:
Node Interface Speed carrier June-01 June-10 Server1 wan1 100 ATT 80 30 Server1 wan2 100 Sprint 60 30 Server1 wan3 100 Verizon 96 15
尝试执行以下代码:
df1=df.pivot(index=['Node', 'Interface', 'Speed', 'Band_In', 'carrier'], columns='Date', values='Speed'/'Interface'*100).fillna('').reset_index()
报错信息:length of passed values is 11,456, index implies 5
错误分析
- 使用率计算逻辑错误:代码中
'Speed'/'Interface'*100是对字符串做运算,不是对DataFrame列进行计算,且正确公式应为(Band_In/Speed)*100,而非Speed除以Interface。 - pivot索引参数错误:将
Band_In加入索引是错误的——不同日期的Band_In值不同,作为索引会导致每个日期的记录被拆分成独立行,无法合并为同一行的多日期列。 - 未处理日期格式:未将原始
Date列转换为需求的“月份名称-日期”格式。 - pivot的values参数用法错误:
values需要传入DataFrame已存在的列名,不能直接写运算表达式,必须预先计算出使用率列再传入。
正确解决方案
按以下步骤处理:
- 计算使用率列,公式为
(Band_In / Speed) * 100 - 将
Date列转换为“月份名称-日期”格式 - 使用
pivot重组数据,索引设为不变维度(Node、Interface、Speed、carrier),列转换后的日期,值为使用率 - 整理列名和索引,优化结果展示
完整代码:
import pandas as pd # 假设原始DataFrame为df # 1. 计算使用率 df['usage'] = (df['Band_In'] / df['Speed']) * 100 # 2. 转换日期格式为June-01 df['Date'] = pd.to_datetime(df['Date']).dt.strftime('%B-%d') # 3. 重组数据 df1 = df.pivot( index=['Node', 'Interface', 'Speed', 'carrier'], columns='Date', values='usage' ).reset_index() # 4. 移除列名的层级标签 df1.columns.name = None print(df1)
执行后得到符合需求的结果,示例片段:
Node Interface Speed carrier June-01 June-10 0 Server1 wan1 100 ATT 80.0 30.0 1 Server1 wan2 100 Sprint 60.0 30.0 2 Server1 wan3 100 Verizon 96.0 15.0 3 Server2 wan1 100 ATT 80.0 80.0 ...
内容的提问来源于stack exchange,提问作者user1471980
相关产品推荐
相关产品推荐

