使用C#从URL读取CSV并计算列平均值出现NaN问题求助
问题原因
- 你当前下载的URL指向的是HTML网页而非纯CSV文件,
client.DownloadString(url)获取的是网页源码,不是目标CSV数据。这导致后续遍历所有行时,找不到任何符合values[0] == "Strom"的条目,count始终为0,计算sum/count时就会出现NaN(数学上0除以0的无意义结果)。 - 额外隐患:直接用
string.Split(',')解析CSV不严谨,若字段包含逗号(比如带引号的文本),会导致拆分错误。
修复步骤
- 替换为真实CSV链接:打开你提供的HTML页面,找到下载按钮对应的真实CSV文件URL(可通过浏览器开发者工具查看网络请求获取),替换代码中的
url变量。 - 添加防除以0判断:计算平均值前先检查
count是否大于0,避免NaN。 - 添加解析容错:用
double.TryParse代替double.Parse,防止数据格式错误导致程序崩溃。 - (可选)使用专业CSV解析库:比如CsvHelper,能更可靠处理各种CSV格式异常。
修改后的示例代码
using System; using System.Net.Http; using System.IO; namespace ETL { class Program { static async System.Threading.Tasks.Task Main(string[] args) { // 替换为实际的CSV文件直接下载URL string csvUrl = "https://example.com/real-data.csv"; // 使用HttpClient替代已过时的WebClient using var client = new HttpClient(); string data = await client.GetStringAsync(csvUrl); string csvFileName = "one.csv"; File.WriteAllText(csvFileName, data); string[] lines = File.ReadAllLines(csvFileName); double sum = 0; int validCount = 0; foreach (string line in lines) { // 跳过空行和表头(根据实际CSV结构调整) if (string.IsNullOrWhiteSpace(line) || line.StartsWith("表头列名")) continue; string[] values = line.Split(','); // 确保数组长度足够,且第一列匹配目标值 if (values.Length >= 2 && values[0].Trim() == "Strom") { if (double.TryParse(values[1].Trim(), out double consumptionValue)) { sum += consumptionValue; validCount++; } } } // 避免除以0,无有效数据时返回0或其他默认值 double average = validCount > 0 ? sum / validCount : 0; string htmlContent = $"<html><body><p>Average power consumption is: {average:F2}</p></body></html>"; File.WriteAllText("index.html", htmlContent); Console.WriteLine($"计算完成,平均值:{average:F2}"); } } }
额外优化建议
- 用
HttpClient替代WebClient:WebClient已被官方标记为过时,HttpClient是更现代、高效的HTTP请求工具。 - 用专业CSV库:比如通过NuGet安装CsvHelper,它能自动处理带引号的字段、换行、表头映射等复杂CSV场景,避免手动拆分的各种问题。
内容的提问来源于stack exchange,提问作者DannyD
相关产品推荐
相关产品推荐

