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

求助:如何实现Python函数每次调用读取CSV文件单行数据

解决Pandas逐行读取CSV并每次返回单行的问题

嘿,我来帮你搞定这个问题!你的代码现在有两个核心问题导致不符合预期:

  1. 每次调用函数都会重置计数器并重新读文件:你在readCsv()里把i初始化为0,而且每次调用都重新读取整个CSV,所以不管循环多少次,你拿到的都是从第0行开始的所有数据,而不是下一行。
  2. 取数方式不对:data.iloc[i:,0]这种写法是获取从第i行到最后一行的整列数据(返回的是Pandas的Series对象),不是单行的单个值。

下面给你两种简单易懂的解决方案,适合Python和Pandas新手:

方案一:使用生成器函数(推荐)

生成器是Python里处理逐行迭代的绝佳工具,它只会读取一次CSV,然后每次调用返回下一行数据,非常高效:

import pandas as pd
import time

def read_csv_generator(file_path):
    # 只读取一次CSV文件,避免重复IO操作
    data = pd.read_csv(file_path)
    # 遍历DataFrame的每一行
    for _, row in data.iterrows():
        # 返回当前行的5列数据
        yield row[0], row[1], row[2], row[3], row[4]

# 创建生成器实例,此时已经完成文件读取
csv_reader = read_csv_generator("/home/oztron/Documents/energylogger2.csv")

while True:
    try:
        # 每次获取下一行数据
        t, e, p, v, c = next(csv_reader)
        print(t)
        time.sleep(10)
    except StopIteration:
        # 当所有行都读完时,捕获停止迭代的异常
        print("所有CSV数据已读取完毕,退出循环")
        break

代码说明:

  • read_csv_generator是一个生成器函数,用yield关键字返回数据,每次调用next()时才会执行到下一个yield。
  • iterrows()会遍历DataFrame的每一行,返回行索引和行数据(我们用_忽略索引)。
  • 当所有行都读完后,生成器会抛出StopIteration异常,我们捕获它来结束循环。

方案二:使用闭包保存状态

如果你觉得生成器有点抽象,也可以用闭包来保存计数器和已读取的CSV数据,这样每次调用读取函数时,计数器会持续递增:

import pandas as pd
import time

def create_csv_reader(file_path):
    # 一次性读取整个CSV
    data = pd.read_csv(file_path)
    row_index = 0
    total_rows = len(data)
    
    def read_single_row():
        nonlocal row_index
        # 检查是否已经读完所有行
        if row_index >= total_rows:
            return None
        # 获取当前行的单个值(注意用iloc[i, col],不是i:)
        t = data.iloc[row_index, 0]
        e = data.iloc[row_index, 1]
        p = data.iloc[row_index, 2]
        v = data.iloc[row_index, 3]
        c = data.iloc[row_index, 4]
        # 计数器递增
        row_index += 1
        return t, e, p, v, c
    
    return read_single_row

# 创建读取函数,此时已经加载了CSV数据
read_csv = create_csv_reader("/home/oztron/Documents/energylogger2.csv")

while True:
    row_data = read_csv()
    if row_data is None:
        print("所有数据已读取完成")
        break
    t, e, p, v, c = row_data
    print(t)
    time.sleep(10)

代码说明:

  • create_csv_reader是一个外部函数,负责读取CSV并初始化计数器,然后返回内部函数read_single_row。
  • nonlocal关键字让内部函数可以修改外部函数的row_index变量,避免每次调用都重置计数器。
  • data.iloc[row_index, 0]是获取第row_index行第0列的单个值,这才是你需要的单行单个数据。

为什么你的原代码sleep生效了但看起来不对?

其实你的time.sleep(10)是生效的,但因为每次调用readCsv()都重新读取文件并从第0行开始返回所有行,所以你每次打印的都是整个第一列的Series,看起来像是重复输出,导致你误以为sleep没起作用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:06:43