因为我需要读取的一些CSV文件非常大(多GB),所以我try 实现一个进度条,该进度条指示使用pandas从URL读取CSV文件时读取的总字节数.

我正在try 实现这样的功能:

from tqdm import tqdm
import requests
from sodapy import Socrata
import contextlib
import urllib
import pandas as pd

url = "https://public.tableau.com/views/PPBOpenDataDownloads/UseOfForce-All.csv?:showVizHome=no"

response = requests.get(url, params=None, stream=True)
response.raise_for_status()
total_size = int(response.headers.get('Content-Length', 0))

block_size = 1000
df = []
last_position = 0
cur_position = 1
with tqdm(desc=url, total=total_size,
     unit='iB',
     unit_scale=True,
     unit_divisor=1024
     ) as bar:
    with contextlib.closing(urllib.request.urlopen(url=url)) as rd:
        # Create TextFileReader
        reader = pd.read_csv(rd, chunksize=block_size)
        for chunk in reader:
            df.append(chunk)
            # Here I would like to calculate the current file position: cur_position 
            bar.update(cur_position - last_position)
            last_position = cur_position

有没有办法从pandas TextFileReader获取文件位置?对于TextFileReader,可能有与C++中的ftell等效的东西?

推荐答案

虽然没有经过彻底测试,但您可以使用read()方法实现自定义类,其中您可以逐行读取requests个响应并更新tqdm条:

import requests
import pandas as pd
from tqdm import tqdm

url = "https://public.tableau.com/views/PPBOpenDataDownloads/UseOfForce-All.csv?:showVizHome=no"


class TqdmReader:
    def __init__(self, resp):
        total_size = int(resp.headers.get("Content-Length", 0))

        self.resp = resp
        self.bar = tqdm(
            desc=resp.url,
            total=total_size,
            unit="iB",
            unit_scale=True,
            unit_divisor=1024,
        )

        self.reader = self.read_from_stream()

    def read_from_stream(self):
        for line in self.resp.iter_lines():
            line += b"\n"
            self.bar.update(len(line))
            yield line

    def read(self, n=0):
        try:
            return next(self.reader)
        except StopIteration:
            return ""


with requests.get(url, params=None, stream=True) as resp:
    df = pd.read_csv(TqdmReader(resp))

print(len(df))

打印:

https://public.tableau.com/views/PPBOpenDataDownloads/UseOfForce-All.csv?:showVizHome=no: 100%|██████████████████████████████████████████████████████████████████████████████| 2.09M/2.09M [00:00<00:00, 2.64MiB/s]
7975

Python相关问答推荐

找到相对于列表索引的当前最大值列表""

基于另一列的GROUP-BY聚合将列添加到Polars LazyFrame

Gekko中基于时间的间隔约束

在Google Drive中获取特定文件夹内的FolderID和文件夹名称

Polars Group by描述扩展

如何在Python请求中组合多个适配器?

如何将一组组合框重置回无 Select tkinter?

每次查询的流通股数量

pytest、xdist和共享生成的文件依赖项

设置索引值每隔17行左右更改的索引

高效地计算数字数组中三行上三个点之间的Angular

使用美汤对维基百科表格进行网络刮擦未返回任何内容

Pandas 数据框自定义排序功能

在Pandas 中,有没有办法让元组作为索引运行得很好?

在错误处理期间使用字典理解中的变量是否安全?

我的tkinter应用程序不会改变它正在加载的文件

基于时间间隔扩展Pandas DataFrame中的行,考虑可选中断

设置gtuner计算机视觉时遇到问题

BeautifulSoup:迭代元素列表并按类提取文本

Microsoft Autogen中的流功能