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

如何用Python删除CSV文件空白行?解决浮点转换报错问题

解决CSV浮点相加崩溃问题:处理空行与代码优化

Hey there! Let's fix that ValueError and clean up your code at the same time. The root issue is that you're trying to convert empty strings (or invalid values like >>>) to floats, which Python can't handle. Plus, we can make your code much cleaner instead of deleting all those unwanted fields one by one.

核心解决方案:处理空值与过滤无效行

1. 安全转换浮点数值

Instead of directly calling float() on the field values, create a helper function that handles empty strings or invalid inputs gracefully. This will prevent your script from crashing when it hits bad data.

2. 过滤空白/无效行

Before processing each row, check if the required numeric fields have valid values. If they're empty or invalid, skip that row entirely.

3. 优化字段处理

Instead of deleting every unwanted field, just keep the ones you need. This is more efficient and easier to read.

优化后的完整代码

#! python3
# automatedReport.py - Reads and writes a new CSV file with
# Campaign Name, Group Name, Raised from Apr 1st-Apr 30th Total,
# Donation from Apr 1st-Apr 30th Total, and Campaign Total Apr 1st-Apr 30th.

import csv
import os
import ctypes

MessageBox = ctypes.windll.user32.MessageBoxW

def safe_float_convert(value):
    """Safely convert a string to float, return 0 if conversion fails or value is empty."""
    try:
        return float(value.strip()) if value.strip() else 0.0
    except ValueError:
        return 0.0

# Find out whether or not campaign_monthly_report is present.
if os.path.isfile('campaign_monthly_report.csv'):
    os.makedirs('automatedReport', exist_ok=True)
    print('Organizing campaign_monthly_report.csv...')

    # Define the fields we WANT to keep
    desired_fields = [
        'Campaign Name',
        'Group Name',
        'Raised from Apr 1st-Apr 30th Total',
        'Donation from Apr 1st-Apr 30th Total'
    ]
    output_fields = desired_fields + ['Campaign Total Apr 1st-Apr 30th']

    # Read the CSV file and write the output
    with open('campaign_monthly_report.csv', 'r') as csv_file, \
         open(os.path.join('automatedReport', 'automated_campaign_monthly_report.csv'), 'w', newline='') as new_file:
        
        csv_reader = csv.DictReader(csv_file)
        csv_writer = csv.DictWriter(new_file, fieldnames=output_fields)
        csv_writer.writeheader()

        for line in csv_reader:
            # Extract only the fields we need
            cleaned_line = {field: line[field] for field in desired_fields}
            
            # Get safe float values
            raised_total = safe_float_convert(cleaned_line['Raised from Apr 1st-Apr 30th Total'])
            donation_total = safe_float_convert(cleaned_line['Donation from Apr 1st-Apr 30th Total'])
            
            # Skip rows where both values are 0 (optional, adjust based on your needs)
            if raised_total == 0.0 and donation_total == 0.0:
                continue
            
            # Calculate and add the total
            campaign_total = raised_total + donation_total
            cleaned_line['Campaign Total Apr 1st-Apr 30th'] = campaign_total
            
            # Write the row
            csv_writer.writerow(cleaned_line)
            print(campaign_total)

    MessageBox(None, "Process Complete. Locate output in the automatedReport folder.", "Success!", 0)
else:
    MessageBox(None, "campaign_monthly_report not found!", "Error!", 0)

关键改进点说明

  • safe_float_convert函数:这个函数会处理空字符串、前后空格,以及无效的数值格式,返回0.0而不是抛出错误,让你的脚本更健壮。
  • 字段保留而非删除:通过定义desired_fields,我们直接提取需要的字段,避免了一堆del语句,代码更简洁易维护。
  • 无效行过滤:如果某行的两个数值字段都是0(或者你可以改成判断是否为空),我们直接跳过该行,避免写入无用数据。
  • 上下文管理器嵌套:把两个with语句合并,让代码更简洁,同时确保文件正确关闭。

额外建议

  • 如果你的CSV文件中有表头之后的完全空白行,csv.DictReader其实会自动跳过它们,但如果是有表头但字段为空的行,上面的代码会处理。
  • 如果需要保留行即使其中一个字段为空(比如只计算存在的数值),可以去掉if raised_total == 0.0 and donation_total == 0.0: continue这一行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:55:06