活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

深入探索pandas表格输出的多种方法与实用技巧让数据分析结果更加专业直观提升工作效率与职场竞争力解决数据展示难题

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-2 12:50:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

在数据分析和处理领域,pandas作为Python的核心库之一,为我们提供了强大的数据处理能力。然而,仅仅能够处理数据是不够的,如何有效地展示和分析结果同样重要。专业的表格输出不仅能让数据更加直观,还能显著提升工作效率和职场竞争力。本文将深入探索pandas表格输出的多种方法与实用技巧,帮助读者解决数据展示难题,让数据分析结果更加专业直观。

基础表格输出方法

print()函数

最基础的输出方法是使用Python内置的print()函数。这种方法简单直接,但在处理大型数据集时可能不够美观。
  1. import pandas as pd
  2. import numpy as np
  3. # 创建示例数据
  4. data = {
  5.     '姓名': ['张三', '李四', '王五', '赵六', '钱七'],
  6.     '年龄': [28, 34, 29, 42, 31],
  7.     '部门': ['技术部', '市场部', '财务部', '技术部', '人力资源部'],
  8.     '薪资': [12000, 15000, 9000, 18000, 11000]
  9. }
  10. df = pd.DataFrame(data)
  11. # 使用print()输出
  12. print(df)
复制代码

输出结果:
  1. 姓名  年龄      部门     薪资
  2. 0  张三  28    技术部  12000
  3. 1  李四  34    市场部  15000
  4. 2  王五  29    财务部   9000
  5. 3  赵六  42    技术部  18000
  6. 4  钱七  31  人力资源部  11000
复制代码

display()函数(在Jupyter Notebook中)

在Jupyter Notebook环境中,display()函数提供了更美观的输出效果:
  1. # 在Jupyter Notebook中使用
  2. from IPython.display import display
  3. display(df)
复制代码

这将在Notebook中渲染出一个美观的表格,支持滚动和交互功能。

to_string()方法

to_string()方法允许我们将DataFrame转换为字符串格式,提供了更多的自定义选项:
  1. # 使用to_string()方法
  2. print(df.to_string(index=False))  # 不显示索引
  3. # 自定义格式
  4. print(df.to_string(
  5.     index=False,
  6.     justify='center',  # 文本居中对齐
  7.     col_space=15,      # 列宽
  8.     show_dimensions=True  # 显示维度信息
  9. ))
复制代码

格式化输出技巧

设置显示选项

pandas提供了多种设置显示选项的方法,可以全局控制输出格式:
  1. # 设置显示选项
  2. pd.set_option('display.max_rows', 10)         # 最大显示行数
  3. pd.set_option('display.max_columns', 10)      # 最大显示列数
  4. pd.set_option('display.width', 1000)          # 显示宽度
  5. pd.set_option('display.precision', 2)         # 小数点精度
  6. pd.set_option('display.float_format', '{:.2f}'.format)  # 浮点数格式
  7. # 创建包含浮点数的示例数据
  8. np.random.seed(42)
  9. float_data = pd.DataFrame({
  10.     'A': np.random.randn(5),
  11.     'B': np.random.randn(5),
  12.     'C': np.random.randn(5)
  13. })
  14. print(float_data)
  15. # 重置选项
  16. pd.reset_option('all')
复制代码

样式设置(Styling)

pandas的Styler对象提供了强大的表格样式设置功能:
  1. # 基本样式设置
  2. styled_df = df.style.set_properties(**{
  3.     'background-color': '#f7f7f9',
  4.     'color': 'black',
  5.     'border-color': 'white',
  6.     'border-style': 'solid',
  7.     'border-width': '1px'
  8. })
  9. # 在Jupyter Notebook中显示
  10. styled_df
复制代码
  1. # 更高级的样式设置
  2. styled_df = df.style \
  3.     .set_caption('员工信息表') \  # 添加标题
  4.     .set_properties(**{'text-align': 'center'}) \  # 文本居中
  5.     .hide_index() \  # 隐藏索引
  6.     .background_gradient(cmap='Blues', subset=['年龄', '薪资']) \  # 背景渐变
  7.     .highlight_max(subset=['薪资'], color='red') \  # 高亮最大值
  8.     .highlight_min(subset=['薪资'], color='green')  # 高亮最小值
  9. styled_df
复制代码

条件格式化

条件格式化可以根据数据值动态设置样式:
  1. # 条件格式化示例
  2. def highlight_high_salary(val):
  3.     color = 'red' if val > 15000 else 'black'
  4.     return f'color: {color}'
  5. styled_df = df.style.applymap(highlight_high_salary, subset=['薪资'])
  6. styled_df
复制代码
  1. # 更复杂的条件格式化
  2. def style_by_department(val):
  3.     if val == '技术部':
  4.         return 'background-color: #e6f2ff'
  5.     elif val == '市场部':
  6.         return 'background-color: #fff2e6'
  7.     elif val == '财务部':
  8.         return 'background-color: #e6ffe6'
  9.     else:
  10.         return 'background-color: #f2e6ff'
  11. styled_df = df.style.applymap(style_by_department, subset=['部门'])
  12. styled_df
复制代码

高级输出方法

转换为HTML

将DataFrame转换为HTML格式,便于在网页或邮件中展示:
  1. # 转换为HTML
  2. html_table = df.to_html(
  3.     index=False,           # 不显示索引
  4.     classes='table table-striped',  # 添加CSS类
  5.     table_id='employee_table',       # 设置表格ID
  6.     border=0,              # 边框宽度
  7.     justify='center'       # 对齐方式
  8. )
  9. # 保存为HTML文件
  10. with open('employee_table.html', 'w', encoding='utf-8') as f:
  11.     f.write(f"""
  12.     <!DOCTYPE html>
  13.     <html>
  14.     <head>
  15.         <title>员工信息表</title>
  16.         <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  17.         <style>
  18.             body {{ padding: 20px; }}
  19.             .container {{ max-width: 800px; margin: 0 auto; }}
  20.             h1 {{ color: #333; }}
  21.         </style>
  22.     </head>
  23.     <body>
  24.         <div class="container">
  25.             <h1>员工信息表</h1>
  26.             {html_table}
  27.         </div>
  28.     </body>
  29.     </html>
  30.     """)
复制代码

转换为Markdown

将DataFrame转换为Markdown格式,便于在文档和README文件中使用:
  1. # 转换为Markdown
  2. markdown_table = df.to_markdown(
  3.     index=False,
  4.     tablefmt='grid',
  5.     stralign='center',
  6.     numalign='center'
  7. )
  8. print(markdown_table)
  9. # 保存为Markdown文件
  10. with open('employee_table.md', 'w', encoding='utf-8') as f:
  11.     f.write("# 员工信息表\n\n")
  12.     f.write(markdown_table)
复制代码

转换为LaTeX

将DataFrame转换为LaTeX格式,便于在学术论文和报告中使用:
  1. # 转换为LaTeX
  2. latex_table = df.to_latex(
  3.     index=False,
  4.     caption='员工信息表',
  5.     label='tab:employee',
  6.     position='htbp',
  7.     column_format='|c|c|c|c|',
  8.     escape=False
  9. )
  10. print(latex_table)
  11. # 保存为LaTeX文件
  12. with open('employee_table.tex', 'w', encoding='utf-8') as f:
  13.     f.write("\\documentclass{article}\n")
  14.     f.write("\\usepackage[utf8]{inputenc}\n")
  15.     f.write("\\usepackage{booktabs}\n")
  16.     f.write("\\begin{document}\n\n")
  17.     f.write(latex_table)
  18.     f.write("\n\\end{document}")
复制代码

转换为Excel

将DataFrame转换为Excel格式,便于在电子表格软件中进一步处理:
  1. # 转换为Excel
  2. with pd.ExcelWriter('employee_table.xlsx', engine='xlsxwriter') as writer:
  3.     df.to_excel(
  4.         writer,
  5.         sheet_name='员工信息',
  6.         index=False,
  7.         startrow=1,  # 从第二行开始写入,留出标题行
  8.         header=False  # 不写入列名,因为我们将在下面自定义标题
  9.     )
  10.    
  11.     # 获取工作簿和工作表对象
  12.     workbook = writer.book
  13.     worksheet = writer.sheets['员工信息']
  14.    
  15.     # 添加标题格式
  16.     header_format = workbook.add_format({
  17.         'bold': True,
  18.         'text_wrap': True,
  19.         'valign': 'top',
  20.         'fg_color': '#D7E4BC',
  21.         'border': 1
  22.     })
  23.    
  24.     # 写入标题
  25.     for col_num, value in enumerate(df.columns.values):
  26.         worksheet.write(0, col_num, value, header_format)
  27.    
  28.     # 设置列宽
  29.     worksheet.set_column('A:D', 15)
  30.    
  31.     # 添加表格样式
  32.     (max_row, max_col) = df.shape
  33.     worksheet.add_table(
  34.         0, 0, max_row, max_col - 1,
  35.         {
  36.             'columns': [{'header': column} for column in df.columns],
  37.             'style': 'Table Style Medium 9'
  38.         }
  39.     )
  40.    
  41.     # 添加条件格式
  42.     worksheet.conditional_format(
  43.         1, 3, max_row, 3,  # D列(薪资)
  44.         {
  45.             'type': 'data_bar',
  46.             'bar_color': '#63C384'
  47.         }
  48.     )
复制代码

可视化输出

结合matplotlib/seaborn

将表格与可视化图表结合,提供更直观的数据展示:
  1. import matplotlib.pyplot as plt
  2. import seaborn as sns
  3. # 设置中文字体
  4. plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
  5. plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
  6. # 创建图表
  7. fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
  8. # 部门人数分布
  9. dept_counts = df['部门'].value_counts()
  10. ax1.pie(dept_counts, labels=dept_counts.index, autopct='%1.1f%%', startangle=90)
  11. ax1.set_title('部门人数分布')
  12. # 薪资分布
  13. sns.barplot(x='姓名', y='薪资', data=df, ax=ax2)
  14. ax2.set_title('员工薪资分布')
  15. ax2.set_xlabel('姓名')
  16. ax2.set_ylabel('薪资')
  17. plt.tight_layout()
  18. plt.savefig('employee_visualization.png', dpi=300, bbox_inches='tight')
  19. plt.show()
  20. # 将表格和图表结合输出
  21. fig, ax = plt.subplots(figsize=(10, 4))
  22. ax.axis('tight')
  23. ax.axis('off')
  24. # 创建表格
  25. table = ax.table(
  26.     cellText=df.values,
  27.     colLabels=df.columns,
  28.     cellLoc='center',
  29.     loc='center'
  30. )
  31. # 设置表格样式
  32. table.auto_set_font_size(False)
  33. table.set_fontsize(10)
  34. table.scale(1.2, 1.5)
  35. # 高亮薪资列
  36. for i in range(len(df)):
  37.     if df.iloc[i]['薪资'] > 15000:
  38.         table[(i+1, 3)].set_facecolor('#ffcccc')
  39.     elif df.iloc[i]['薪资'] < 10000:
  40.         table[(i+1, 3)].set_facecolor('#ccffcc')
  41. plt.title('员工信息表', fontsize=14, fontweight='bold')
  42. plt.savefig('employee_table_visualization.png', dpi=300, bbox_inches='tight')
  43. plt.show()
复制代码

交互式表格输出

使用第三方库创建交互式表格,提升用户体验:
  1. # 使用ipywidgets创建交互式表格
  2. from ipywidgets import interact, Dropdown
  3. # 创建交互式函数
  4. @interact
  5. def show_records_more_than(column=['年龄', '薪资'],
  6.                           threshold=(0, 20000, 1000)):
  7.     display(df[df[column] > threshold])
  8. # 使用qgrid创建交互式表格
  9. try:
  10.     import qgrid
  11.     qgrid_widget = qgrid.show_grid(df, show_toolbar=True)
  12.     qgrid_widget
  13. except ImportError:
  14.     print("请先安装qgrid: pip install qgrid")
  15. # 使用itables创建交互式表格
  16. try:
  17.     from itables import show
  18.     show(df)
  19. except ImportError:
  20.     print("请先安装itables: pip install itables")
复制代码

实用案例与最佳实践

大数据集处理技巧

当处理大型数据集时,直接输出整个表格可能不切实际。以下是一些处理大数据集的技巧:
  1. # 创建大型数据集
  2. large_df = pd.DataFrame({
  3.     'ID': range(1, 10001),
  4.     'Value': np.random.randn(10000),
  5.     'Category': np.random.choice(['A', 'B', 'C', 'D'], 10000)
  6. })
  7. # 1. 使用head()和tail()查看数据的前几行和后几行
  8. print("前5行数据:")
  9. print(large_df.head())
  10. print("\n后5行数据:")
  11. print(large_df.tail())
  12. # 2. 使用sample()随机抽样
  13. print("\n随机抽样10行:")
  14. print(large_df.sample(10))
  15. # 3. 分组统计
  16. print("\n按类别分组统计:")
  17. print(large_df.groupby('Category').agg({
  18.     'Value': ['count', 'mean', 'std']
  19. }))
  20. # 4. 使用describe()获取描述性统计
  21. print("\n描述性统计:")
  22. print(large_df.describe())
  23. # 5. 设置显示选项以适应大数据集
  24. pd.set_option('display.max_rows', 20)
  25. pd.set_option('display.max_columns', 10)
  26. print("\n设置显示选项后的输出:")
  27. print(large_df)
复制代码

报表生成自动化

自动化报表生成可以大大提高工作效率:
  1. # 创建报表生成函数
  2. def generate_report(data, output_format='html'):
  3.     """生成数据报表
  4.    
  5.     Args:
  6.         data: DataFrame, 输入数据
  7.         output_format: str, 输出格式 ('html', 'excel', 'markdown')
  8.    
  9.     Returns:
  10.         根据输出格式返回报表或保存文件
  11.     """
  12.     # 计算基本统计信息
  13.     stats = data.describe()
  14.    
  15.     # 按部门分组统计
  16.     dept_stats = data.groupby('部门').agg({
  17.         '年龄': ['mean', 'min', 'max'],
  18.         '薪资': ['mean', 'min', 'max', 'sum']
  19.     })
  20.    
  21.     # 格式化输出
  22.     if output_format == 'html':
  23.         # 创建HTML报表
  24.         html = f"""
  25.         <!DOCTYPE html>
  26.         <html>
  27.         <head>
  28.             <title>员工数据报表</title>
  29.             <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  30.             <style>
  31.                 body {{ padding: 20px; }}
  32.                 .container {{ max-width: 1200px; margin: 0 auto; }}
  33.                 h1, h2 {{ color: #333; margin-top: 30px; }}
  34.                 .table {{ margin-top: 20px; }}
  35.                 .summary {{ background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin-bottom: 20px; }}
  36.             </style>
  37.         </head>
  38.         <body>
  39.             <div class="container">
  40.                 <h1>员工数据报表</h1>
  41.                 <p class="text-muted">生成时间: {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
  42.                
  43.                 <div class="summary">
  44.                     <h2>数据概览</h2>
  45.                     <p>员工总数: <strong>{len(data)}</strong> 人</p>
  46.                     <p>平均年龄: <strong>{data['年龄'].mean():.1f}</strong> 岁</p>
  47.                     <p>平均薪资: <strong>{data['薪资'].mean():.2f}</strong> 元</p>
  48.                     <p>薪资总额: <strong>{data['薪资'].sum():.2f}</strong> 元</p>
  49.                 </div>
  50.                
  51.                 <h2>员工详细信息</h2>
  52.                 {data.to_html(index=False, classes='table table-striped')}
  53.                
  54.                 <h2>基本统计信息</h2>
  55.                 {stats.to_html(classes='table table-striped')}
  56.                
  57.                 <h2>部门统计信息</h2>
  58.                 {dept_stats.to_html(classes='table table-striped')}
  59.             </div>
  60.         </body>
  61.         </html>
  62.         """
  63.         
  64.         # 保存HTML文件
  65.         with open('employee_report.html', 'w', encoding='utf-8') as f:
  66.             f.write(html)
  67.         
  68.         return html
  69.    
  70.     elif output_format == 'excel':
  71.         # 创建Excel报表
  72.         with pd.ExcelWriter('employee_report.xlsx', engine='xlsxwriter') as writer:
  73.             # 写入原始数据
  74.             data.to_excel(writer, sheet_name='员工信息', index=False)
  75.             
  76.             # 写入统计信息
  77.             stats.to_excel(writer, sheet_name='基本统计')
  78.             
  79.             # 写入部门统计
  80.             dept_stats.to_excel(writer, sheet_name='部门统计')
  81.             
  82.             # 获取工作簿对象
  83.             workbook = writer.book
  84.             
  85.             # 添加格式
  86.             header_format = workbook.add_format({
  87.                 'bold': True,
  88.                 'text_wrap': True,
  89.                 'valign': 'top',
  90.                 'fg_color': '#D7E4BC',
  91.                 'border': 1
  92.             })
  93.             
  94.             # 为每个工作表添加格式
  95.             for sheetname in writer.sheets:
  96.                 worksheet = writer.sheets[sheetname]
  97.                
  98.                 # 设置列宽
  99.                 for i, col in enumerate(worksheet.columns):
  100.                     max_len = max([len(str(cell.value)) for cell in col])
  101.                     worksheet.set_column(i, i, max_len + 2)
  102.         
  103.         return "Excel报表已生成: employee_report.xlsx"
  104.    
  105.     elif output_format == 'markdown':
  106.         # 创建Markdown报表
  107.         md = f"""# 员工数据报表
  108. 生成时间: {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}
  109. ## 数据概览
  110. - 员工总数: **{len(data)}** 人
  111. - 平均年龄: **{data['年龄'].mean():.1f}** 岁
  112. - 平均薪资: **{data['薪资'].mean():.2f}** 元
  113. - 薪资总额: **{data['薪资'].sum():.2f}** 元
  114. ## 员工详细信息
  115. {data.to_markdown(index=False)}
  116. ## 基本统计信息
  117. {stats.to_markdown()}
  118. ## 部门统计信息
  119. {dept_stats.to_markdown()}
  120. """
  121.         
  122.         # 保存Markdown文件
  123.         with open('employee_report.md', 'w', encoding='utf-8') as f:
  124.             f.write(md)
  125.         
  126.         return md
  127.    
  128.     else:
  129.         return "不支持的输出格式"
  130. # 生成HTML报表
  131. html_report = generate_report(df, 'html')
  132. print("HTML报表已生成")
  133. # 生成Excel报表
  134. excel_result = generate_report(df, 'excel')
  135. print(excel_result)
  136. # 生成Markdown报表
  137. md_report = generate_report(df, 'markdown')
  138. print("Markdown报表已生成")
复制代码

职场应用场景

在职场中,专业的数据展示可以显著提升工作效率和竞争力。以下是一些实际应用场景:
  1. # 创建销售数据
  2. sales_data = pd.DataFrame({
  3.     '月份': ['1月', '2月', '3月', '4月', '5月', '6月'],
  4.     '销售额': [120000, 135000, 148000, 162000, 155000, 178000],
  5.     '成本': [80000, 85000, 90000, 95000, 98000, 105000],
  6.     '利润': [40000, 50000, 58000, 67000, 57000, 73000]
  7. })
  8. # 计算利润率
  9. sales_data['利润率'] = sales_data['利润'] / sales_data['销售额'] * 100
  10. # 创建销售分析报告
  11. def create_sales_report(data):
  12.     # 创建图表
  13.     fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
  14.    
  15.     # 销售额和成本趋势图
  16.     ax1.plot(data['月份'], data['销售额'], 'o-', label='销售额')
  17.     ax1.plot(data['月份'], data['成本'], 's-', label='成本')
  18.     ax1.set_title('销售额与成本趋势')
  19.     ax1.set_ylabel('金额 (元)')
  20.     ax1.legend()
  21.     ax1.grid(True)
  22.    
  23.     # 利润率柱状图
  24.     ax2.bar(data['月份'], data['利润率'], color='green', alpha=0.7)
  25.     ax2.set_title('利润率变化')
  26.     ax2.set_ylabel('利润率 (%)')
  27.     ax2.set_ylim(0, 50)
  28.     ax2.grid(True, axis='y')
  29.    
  30.     plt.tight_layout()
  31.     plt.savefig('sales_analysis.png', dpi=300, bbox_inches='tight')
  32.    
  33.     # 创建HTML报告
  34.     html = f"""
  35.     <!DOCTYPE html>
  36.     <html>
  37.     <head>
  38.         <title>销售数据分析报告</title>
  39.         <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  40.         <style>
  41.             body {{ padding: 20px; }}
  42.             .container {{ max-width: 1000px; margin: 0 auto; }}
  43.             h1, h2 {{ color: #333; margin-top: 30px; }}
  44.             .table {{ margin-top: 20px; }}
  45.             .summary {{ background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin-bottom: 20px; }}
  46.             .chart {{ text-align: center; margin: 30px 0; }}
  47.             .positive {{ color: green; }}
  48.             .negative {{ color: red; }}
  49.         </style>
  50.     </head>
  51.     <body>
  52.         <div class="container">
  53.             <h1>销售数据分析报告</h1>
  54.             <p class="text-muted">生成时间: {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
  55.             
  56.             <div class="summary">
  57.                 <h2>数据概览</h2>
  58.                 <p>总销售额: <strong>{data['销售额'].sum():,.2f}</strong> 元</p>
  59.                 <p>总成本: <strong>{data['成本'].sum():,.2f}</strong> 元</p>
  60.                 <p>总利润: <strong>{data['利润'].sum():,.2f}</strong> 元</p>
  61.                 <p>平均利润率: <strong>{data['利润率'].mean():.2f}%</strong></p>
  62.                 <p>最高利润率: <strong>{data['利润率'].max():.2f}%</strong> ({data.loc[data['利润率'].idxmax(), '月份']})</p>
  63.             </div>
  64.             
  65.             <div class="chart">
  66.                 <h2>销售趋势分析</h2>
  67.                 <img src="sales_analysis.png" alt="销售趋势分析" class="img-fluid">
  68.             </div>
  69.             
  70.             <h2>月度销售数据</h2>
  71.             {data.to_html(index=False, classes='table table-striped')}
  72.             
  73.             <h2>环比分析</h2>
  74.             <table class="table table-striped">
  75.                 <thead>
  76.                     <tr>
  77.                         <th>月份</th>
  78.                         <th>销售额环比</th>
  79.                         <th>利润环比</th>
  80.                         <th>利润率变化</th>
  81.                     </tr>
  82.                 </thead>
  83.                 <tbody>
  84.             """
  85.    
  86.     # 添加环比数据
  87.     for i in range(1, len(data)):
  88.         sales_change = (data.iloc[i]['销售额'] - data.iloc[i-1]['销售额']) / data.iloc[i-1]['销售额'] * 100
  89.         profit_change = (data.iloc[i]['利润'] - data.iloc[i-1]['利润']) / data.iloc[i-1]['利润'] * 100
  90.         margin_change = data.iloc[i]['利润率'] - data.iloc[i-1]['利润率']
  91.         
  92.         html += f"""
  93.                     <tr>
  94.                         <td>{data.iloc[i]['月份']}</td>
  95.                         <td class="{'positive' if sales_change > 0 else 'negative'}">{sales_change:.2f}%</td>
  96.                         <td class="{'positive' if profit_change > 0 else 'negative'}">{profit_change:.2f}%</td>
  97.                         <td class="{'positive' if margin_change > 0 else 'negative'}">{margin_change:.2f}%</td>
  98.                     </tr>
  99.         """
  100.    
  101.     html += """
  102.                 </tbody>
  103.             </table>
  104.             
  105.             <h2>分析结论</h2>
  106.             <ul>
  107.                 <li>销售额整体呈上升趋势,6月份达到最高点178,000元</li>
  108.                 <li>利润率在4月份达到最高点41.36%,之后有所回落</li>
  109.                 <li>建议进一步分析5月份利润率下降的原因,并采取措施提升利润率</li>
  110.             </ul>
  111.         </div>
  112.     </body>
  113.     </html>
  114.     """
  115.    
  116.     # 保存HTML文件
  117.     with open('sales_report.html', 'w', encoding='utf-8') as f:
  118.         f.write(html)
  119.    
  120.     return html
  121. # 生成销售报告
  122. sales_report = create_sales_report(sales_data)
  123. print("销售分析报告已生成")
复制代码
  1. # 创建项目数据
  2. projects_data = pd.DataFrame({
  3.     '项目名称': ['网站重构', '移动应用开发', '数据分析平台', '客户管理系统', '市场推广活动'],
  4.     '负责人': ['张三', '李四', '王五', '赵六', '钱七'],
  5.     '开始日期': ['2023-01-15', '2023-02-01', '2023-03-10', '2023-01-20', '2023-04-01'],
  6.     '计划完成日期': ['2023-04-30', '2023-05-15', '2023-06-30', '2023-03-31', '2023-06-15'],
  7.     '实际完成日期': ['2023-04-25', '2023-05-20', None, '2023-04-05', None],
  8.     '进度(%)': [100, 100, 75, 100, 40],
  9.     '预算(万元)': [15, 25, 30, 20, 10],
  10.     '已花费(万元)': [14.5, 26.2, 22.5, 19.8, 4.2]
  11. })
  12. # 转换日期格式
  13. projects_data['开始日期'] = pd.to_datetime(projects_data['开始日期'])
  14. projects_data['计划完成日期'] = pd.to_datetime(projects_data['计划完成日期'])
  15. projects_data['实际完成日期'] = pd.to_datetime(projects_data['实际完成日期'])
  16. # 计算项目状态
  17. def get_project_status(row):
  18.     if row['进度(%)'] == 100:
  19.         if pd.isna(row['实际完成日期']):
  20.             return '已完成(未更新)'
  21.         elif row['实际完成日期'] <= row['计划完成日期']:
  22.             return '按时完成'
  23.         else:
  24.             return '延期完成'
  25.     else:
  26.         if pd.Timestamp.now() > row['计划完成日期']:
  27.             return '进行中(已延期)'
  28.         else:
  29.             return '进行中'
  30. projects_data['状态'] = projects_data.apply(get_project_status, axis=1)
  31. # 计算预算使用率
  32. projects_data['预算使用率(%)'] = projects_data['已花费(万元)'] / projects_data['预算(万元)'] * 100
  33. # 创建项目进度跟踪表
  34. def create_project_status_report(data):
  35.     # 创建HTML报告
  36.     html = f"""
  37.     <!DOCTYPE html>
  38.     <html>
  39.     <head>
  40.         <title>项目进度跟踪报告</title>
  41.         <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  42.         <style>
  43.             body {{ padding: 20px; }}
  44.             .container {{ max-width: 1200px; margin: 0 auto; }}
  45.             h1, h2 {{ color: #333; margin-top: 30px; }}
  46.             .table {{ margin-top: 20px; }}
  47.             .summary {{ background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin-bottom: 20px; }}
  48.             .status-completed {{ color: green; }}
  49.             .status-delayed {{ color: red; }}
  50.             .status-in-progress {{ color: blue; }}
  51.             .progress-bar-container {{ width: 100%; background-color: #f0f0f0; border-radius: 4px; }}
  52.             .progress-bar {{ height: 20px; border-radius: 4px; background-color: #4CAF50; text-align: center; line-height: 20px; color: white; }}
  53.             .budget-ok {{ color: green; }}
  54.             .budget-warning {{ color: orange; }}
  55.             .budget-over {{ color: red; }}
  56.         </style>
  57.     </head>
  58.     <body>
  59.         <div class="container">
  60.             <h1>项目进度跟踪报告</h1>
  61.             <p class="text-muted">生成时间: {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
  62.             
  63.             <div class="summary">
  64.                 <h2>项目概览</h2>
  65.                 <p>总项目数: <strong>{len(data)}</strong> 个</p>
  66.                 <p>已完成项目: <strong>{len(data[data['进度(%)'] == 100])}</strong> 个</p>
  67.                 <p>进行中项目: <strong>{len(data[data['进度(%)'] < 100])}</strong> 个</p>
  68.                 <p>延期项目: <strong>{len(data[data['状态'].str.contains('延期')])}</strong> 个</p>
  69.                 <p>总预算: <strong>{data['预算(万元)'].sum():.1f}</strong> 万元</p>
  70.                 <p>已花费: <strong>{data['已花费(万元)'].sum():.1f}</strong> 万元</p>
  71.                 <p>预算使用率: <strong>{data['已花费(万元)'].sum() / data['预算(万元)'].sum() * 100:.1f}%</strong></p>
  72.             </div>
  73.             
  74.             <h2>项目进度详情</h2>
  75.             <table class="table table-striped">
  76.                 <thead>
  77.                     <tr>
  78.                         <th>项目名称</th>
  79.                         <th>负责人</th>
  80.                         <th>开始日期</th>
  81.                         <th>计划完成日期</th>
  82.                         <th>实际完成日期</th>
  83.                         <th>进度</th>
  84.                         <th>状态</th>
  85.                         <th>预算(万元)</th>
  86.                         <th>已花费(万元)</th>
  87.                         <th>预算使用率</th>
  88.                     </tr>
  89.                 </thead>
  90.                 <tbody>
  91.             """
  92.    
  93.     # 添加项目数据
  94.     for _, row in data.iterrows():
  95.         # 设置状态样式
  96.         if '完成' in row['状态']:
  97.             status_class = 'status-completed'
  98.         elif '延期' in row['状态']:
  99.             status_class = 'status-delayed'
  100.         else:
  101.             status_class = 'status-in-progress'
  102.         
  103.         # 设置预算使用率样式
  104.         if row['预算使用率(%)'] <= 80:
  105.             budget_class = 'budget-ok'
  106.         elif row['预算使用率(%)'] <= 100:
  107.             budget_class = 'budget-warning'
  108.         else:
  109.             budget_class = 'budget-over'
  110.         
  111.         # 格式化日期
  112.         start_date = row['开始日期'].strftime('%Y-%m-%d')
  113.         planned_date = row['计划完成日期'].strftime('%Y-%m-%d')
  114.         actual_date = row['实际完成日期'].strftime('%Y-%m-%d') if pd.notna(row['实际完成日期']) else '-'
  115.         
  116.         html += f"""
  117.                     <tr>
  118.                         <td>{row['项目名称']}</td>
  119.                         <td>{row['负责人']}</td>
  120.                         <td>{start_date}</td>
  121.                         <td>{planned_date}</td>
  122.                         <td>{actual_date}</td>
  123.                         <td>
  124.                             <div class="progress-bar-container">
  125.                                 <div class="progress-bar" style="width: {row['进度(%)']}%">{row['进度(%)']}%</div>
  126.                             </div>
  127.                         </td>
  128.                         <td class="{status_class}">{row['状态']}</td>
  129.                         <td>{row['预算(万元)']}</td>
  130.                         <td>{row['已花费(万元)']}</td>
  131.                         <td class="{budget_class}">{row['预算使用率(%)']:.1f}%</td>
  132.                     </tr>
  133.         """
  134.    
  135.     html += """
  136.                 </tbody>
  137.             </table>
  138.             
  139.             <h2>项目状态分布</h2>
  140.             <div class="row">
  141.                 <div class="col-md-6">
  142.                     <canvas id="statusChart"></canvas>
  143.                 </div>
  144.                 <div class="col-md-6">
  145.                     <canvas id="progressChart"></canvas>
  146.                 </div>
  147.             </div>
  148.             
  149.             <h2>风险与建议</h2>
  150.             <div class="alert alert-warning">
  151.                 <h4>风险提示</h4>
  152.                 <ul>
  153.             """
  154.    
  155.     # 添加风险提示
  156.     delayed_projects = data[data['状态'].str.contains('延期')]
  157.     if not delayed_projects.empty:
  158.         for _, project in delayed_projects.iterrows():
  159.             html += f"<li><strong>{project['项目名称']}</strong> 已延期,请关注进度</li>"
  160.    
  161.     over_budget_projects = data[data['预算使用率(%)'] > 100]
  162.     if not over_budget_projects.empty:
  163.         for _, project in over_budget_projects.iterrows():
  164.             html += f"<li><strong>{project['项目名称']}</strong> 已超出预算,当前使用率 {project['预算使用率(%)']:.1f}%</li>"
  165.    
  166.     html += """
  167.                 </ul>
  168.             </div>
  169.             
  170.             <div class="alert alert-info">
  171.                 <h4>改进建议</h4>
  172.                 <ul>
  173.                     <li>定期召开项目进度会议,及时发现问题并解决</li>
  174.                     <li>对于延期项目,分析原因并调整资源分配</li>
  175.                     <li>加强预算控制,避免超支情况发生</li>
  176.                     <li>建立项目风险预警机制,提前识别潜在问题</li>
  177.                 </ul>
  178.             </div>
  179.         </div>
  180.         
  181.         <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  182.         <script>
  183.             // 项目状态分布图
  184.             const statusCtx = document.getElementById('statusChart').getContext('2d');
  185.             const statusChart = new Chart(statusCtx, {
  186.                 type: 'pie',
  187.                 data: {
  188.                     labels: ['按时完成', '延期完成', '进行中', '进行中(已延期)'],
  189.                     datasets: [{
  190.                         data: [
  191.     """
  192.    
  193.     # 添加状态数据
  194.     status_counts = data['状态'].value_counts()
  195.     html += f"{status_counts.get('按时完成', 0)}, "
  196.     html += f"{status_counts.get('延期完成', 0)}, "
  197.     html += f"{status_counts.get('进行中', 0)}, "
  198.     html += f"{status_counts.get('进行中(已延期)', 0)}"
  199.    
  200.     html += """
  201.                         ],
  202.                         backgroundColor: [
  203.                             '#4CAF50',
  204.                             '#F44336',
  205.                             '#2196F3',
  206.                             '#FF9800'
  207.                         ]
  208.                     }]
  209.                 },
  210.                 options: {
  211.                     responsive: true,
  212.                     plugins: {
  213.                         legend: {
  214.                             position: 'bottom',
  215.                         },
  216.                         title: {
  217.                             display: true,
  218.                             text: '项目状态分布'
  219.                         }
  220.                     }
  221.                 }
  222.             });
  223.             
  224.             // 项目进度图
  225.             const progressCtx = document.getElementById('progressChart').getContext('2d');
  226.             const progressChart = new Chart(progressCtx, {
  227.                 type: 'bar',
  228.                 data: {
  229.                     labels: [
  230.             """
  231.    
  232.     # 添加项目名称
  233.     for project in data['项目名称']:
  234.         html += f"'{project}', "
  235.    
  236.     html = html.rstrip(', ') + """
  237.                     ],
  238.                     datasets: [{
  239.                         label: '进度 (%)',
  240.                         data: [
  241.             """
  242.    
  243.     # 添加进度数据
  244.     for progress in data['进度(%)']:
  245.         html += f"{progress}, "
  246.    
  247.     html = html.rstrip(', ') + """
  248.                         ],
  249.                         backgroundColor: [
  250.                 """
  251.    
  252.     # 根据进度设置颜色
  253.     for progress in data['进度(%)']:
  254.         if progress == 100:
  255.             html += "'#4CAF50', "
  256.         elif progress >= 80:
  257.             html += "'#8BC34A', "
  258.         elif progress >= 50:
  259.             html += "'#FFC107', "
  260.         else:
  261.             html += "'#F44336', "
  262.    
  263.     html = html.rstrip(', ') + """
  264.                         ]
  265.                     }]
  266.                 },
  267.                 options: {
  268.                     responsive: true,
  269.                     plugins: {
  270.                         legend: {
  271.                             display: false
  272.                         },
  273.                         title: {
  274.                             display: true,
  275.                             text: '项目进度'
  276.                         }
  277.                     },
  278.                     scales: {
  279.                         y: {
  280.                             beginAtZero: true,
  281.                             max: 100,
  282.                             title: {
  283.                                 display: true,
  284.                                 text: '进度 (%)'
  285.                             }
  286.                         }
  287.                     }
  288.                 }
  289.             });
  290.         </script>
  291.     </body>
  292.     </html>
  293.     """
  294.    
  295.     # 保存HTML文件
  296.     with open('project_status_report.html', 'w', encoding='utf-8') as f:
  297.         f.write(html)
  298.    
  299.     return html
  300. # 生成项目进度报告
  301. project_report = create_project_status_report(projects_data)
  302. print("项目进度跟踪报告已生成")
复制代码

总结与展望

本文深入探索了pandas表格输出的多种方法与实用技巧,从基础的print()函数到高级的样式设置和交互式表格,涵盖了数据展示的各个方面。通过这些技巧,我们可以让数据分析结果更加专业直观,提升工作效率和职场竞争力。

在实际应用中,选择合适的表格输出方法取决于具体场景和需求。对于简单的数据查看,基础的输出方法就足够了;而对于正式的报告和展示,则需要更加精美的格式和样式。自动化报表生成可以大大提高工作效率,特别是在需要定期生成相似报告的场景中。

随着数据分析和可视化技术的不断发展,pandas的表格输出功能也在不断丰富和完善。未来,我们可以期待更多交互式、动态化的表格输出方式,以及与其他数据可视化工具的更紧密集成。

掌握pandas表格输出的多种方法与技巧,不仅能够解决数据展示难题,还能在职场中展现专业能力,提升个人竞争力。希望本文的内容能够帮助读者更好地利用pandas进行数据展示,为数据分析和决策提供更有力的支持。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则