You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Pandas读取XLSX文件返回NaN值的技术求助

问题分析与解决方案

从你的描述来看,出现NaN值大概率和两个核心环节有关:XLS转XLSX过程中的格式损坏,或者文件未完全下载就被读取,再加上pandas读取参数的小疏漏。咱们一步步拆解解决:

1. 先确认文件本身是否正常

首先手动打开neww.xlsx检查:

  • 是不是存在大量空白行、合并单元格或隐藏行?
  • 转换后的XLSX有没有格式错乱(比如Score列被识别为文本,或单元格有特殊格式)?

如果手动转换的文件本身就有问题,建议直接用pandas跳过转换环节,读取原始XLS后再保存为XLSX:

import pandas as pd
# 直接读取原始XLS文件
raw_data = pd.read_excel(r"C:\selenium\original_file.xls", header=0)
# 保存为干净的XLSX格式
raw_data.to_excel(r"C:\selenium\neww.xlsx", index=False)

2. 优化Selenium的下载等待逻辑

你原来的代码只检查文件是否存在,但有时候文件刚创建还在写入中(尤其是大文件),这时候读取会导致数据不完整。改成等待文件大小稳定,确保下载彻底完成:

import os
import glob
import time

homedir = os.path.expanduser("~")
download_dir = os.path.join(homedir, "Downloads")

def wait_for_complete_download(download_dir):
    start_time = time.time()
    last_file_size = -1
    while True:
        # 查找最新的XLSX文件
        xlsx_files = glob.glob(os.path.join(download_dir, "*.xlsx"))
        if not xlsx_files:
            time.sleep(2)
            continue
        
        latest_file = max(xlsx_files, key=os.path.getctime)
        current_size = os.path.getsize(latest_file)
        
        # 如果文件大小连续两次一致,说明下载完成
        if current_size == last_file_size:
            return latest_file
        last_file_size = current_size
        time.sleep(2)
        
        # 超时保护,防止无限等待
        if time.time() - start_time > 300:
            raise TimeoutError("下载超时,请检查网络或页面状态")

# 替换原有的等待代码
print("等待文件下载...")
latest_file = wait_for_complete_download(download_dir)
print(f"文件已下载完成:{latest_file}")

3. 修正pandas的读取参数

你原来的converters={'Priority Class':str, 1:int}有两个明显问题:

  • 表格列名是Priority而非Priority Class,列名不匹配
  • 用索引1指定列不够稳妥,直接用列名Score更可靠

修改后的读取代码,同时自动清理全空行:

import pandas as pd

# 先预览原始数据,排查问题
data = pd.read_excel(r"C:\selenium\neww.xlsx", header=0)
print("原始数据预览:")
print(data.head(10))
print("\n列数据类型:")
print(data.dtypes)

# 针对性读取并清理无效行
cleaned_data = pd.read_excel(
    r"C:\selenium\neww.xlsx",
    header=0,
    converters={'Priority': str, 'Score': float},  # 指定列的类型
    na_filter=True
).dropna(subset=['Priority', 'Score', 'Date'], how='all')  # 删除全空的行

print("\n清理后的数据:")
print(cleaned_data)

这样处理后,应该就能正常读取到所有分数数据了。如果还有零散NaN,大概率是原表格本身存在空值,可以根据需求用fillna()做补充处理。


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

火山引擎 最新活动