AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79585543
Accepted
rysch
rysch
Asked: 2025-04-22 09:01:35 +0800 CST2025-04-22 09:01:35 +0800 CST 2025-04-22 09:01:35 +0800 CST

Como processar eficientemente um arquivo CSV grande com o Pandas quando a memória é limitada?

  • 772

Estou trabalhando com um arquivo CSV muito grande (cerca de 10 GB) que não cabe na memória do meu computador. Quando tento carregá-lo em um DataFrame do Pandas usando pd.read_csv(), recebo um MemoryError.

Qual é a maneira mais eficiente de processar este arquivo usando o Pandas sem carregar tudo na memória de uma vez? Preciso realizar operações como:

  • Calculando a soma de uma coluna específica.
  • Filtragem de linhas com base em determinadas condições.
  • Agrupamento e agregação de dados.

Meu código:

import pandas as pd
import numpy as np

# Simulate a large CSV file
with open('large_file.csv', 'w') as f:
    for i in range(10000000):  # 10 million rows
        f.write(f'{i},{np.random.rand()},{np.random.randint(0, 10)}\n')


# This line causes a MemoryError
df = pd.read_csv('large_file.csv', names=['id', 'value', 'category'])

# Desired operations (example)
# total_value = df['value'].sum()
# filtered_df = df[df['category'] > 5]
# grouped_df = df.groupby('category')['value'].mean()

print("Processing Complete") # Never Reaches Here.

Tentei usar chunksizein pd.read_csv(), mas não tenho certeza de como executar com eficiência as operações desejadas nos blocos e combinar os resultados. Há outras técnicas ou bibliotecas que eu deva considerar?

python
  • 2 2 respostas
  • 119 Views

2 respostas

  • Voted
  1. Best Answer
    bterwijn
    2025-04-22T09:50:15+08:002025-04-22T09:50:15+08:00

    Talvez faça assim:

    import pandas as pd
    import numpy as np
    from collections import defaultdict
    np.random.seed(0)  # Use same random numbers for testing
    
    # Simulate a large CSV file
    with open('large_file.csv', 'w') as f:
        for i in range(10000000):  # 10 million rows
            f.write(f'{i},{np.random.rand()},{np.random.randint(0, 10)}\n')
    
    # Read in chunks of 100
    chunk_iter = pd.read_csv('large_file.csv', names=['id', 'value', 'category'], chunksize=100)
    
    # Update these for each chunk
    value_sums = defaultdict(float)
    value_counts = defaultdict(int)
    total_value = 0.0
    
    for chunk in chunk_iter:
        total_value += chunk['value'].sum()
        filtered = chunk[chunk['category'] > 5]
        # Group by and update running sums and counts
        group = filtered.groupby('category')['value'].agg(['sum', 'count'])
        for cat, row in group.iterrows():
            value_sums[cat] += row['sum']
            value_counts[cat] += row['count']
    
    # Compute final mean per category
    grouped_mean = {cat: value_sums[cat] / value_counts[cat] for cat in value_sums}
    
    print(f'{total_value=}')
    print(f'{grouped_mean=}')
    print("Processing Complete")
    
    • 2
  2. JonSG
    2025-04-22T21:50:48+08:002025-04-22T21:50:48+08:00

    Se o seu objetivo é garantir baixo uso de memória, eu usaria o csvpacote apenas para transmitir, ler e gravar os dados de interesse. Durante a leitura, eu monitoraria os dados necessários para construir os resultados finais que você busca.

    import csv
    import numpy    # for random
    import json     # for nice printing
    
    ## ---------------------------------
    ## Simulate a CSV file with arbitrary number of rows
    ## ---------------------------------
    def get_next_row(limit):
        for i in range(limit):
            yield f"{i},{numpy.random.rand()},{numpy.random.randint(0, 10)}\n"
    ## ---------------------------------
    
    FIELDNAMES = ["id", "value", "category"]
    FILTERED_FILENAME = "filtered.csv"
    
    ## ---------------------------------
    ## The values you seek
    ## ---------------------------------
    total_value = 0
    grouped_data = {}
    ## ---------------------------------
    
    ## ---------------------------------
    ## A reader that reads from the simulated CSV file
    ## the generator here allows you to test with almost
    ## any size of data
    ## ---------------------------------
    reader = csv.reader(get_next_row(100_000)) # lots of rows. feel free to set to 10m
    ## ---------------------------------
    
    with open(FILTERED_FILENAME, "w", newline="") as filtered_file:
        ## ---------------------------------
        ## Open the filtered file and write the header
        ## ---------------------------------
        writer = csv.writer(filtered_file)
        writer.writerow(FIELDNAMES)
        ## ---------------------------------
    
        ## ---------------------------------
        ## Stream read the CSV file
        ## ---------------------------------
        for row in reader:
            _, value, category = map(float, row)
    
            ## ---------------------------------
            ## construct our running total
            ## ---------------------------------
            total_value += value
            ## ---------------------------------
    
            ## ---------------------------------
            ## Construct grouping on the fly
            ## ---------------------------------
            target = grouped_data.setdefault(category, {"sum":0, "count":0})
            target["sum"] += value
            target["count"] += 1
            ## ---------------------------------
    
            ## ---------------------------------
            ## Stream write filtered data to a new CSV file
            ## ---------------------------------
            if category > 5:
                writer.writerow(row)
            ## ---------------------------------
        ## ---------------------------------
    
    print("Example Results:")
    
    print(f"\tTotal: {total_value}")
    
    print("\tGrouped Totals:")
    for key, value in grouped_data.items():
        print(f"\t\t{key}: {value["sum"] /value["count"]}")
    
    print("\tFiltered:")
    with open(FILTERED_FILENAME, "r") as filtered_file:
        reader = csv.reader(filtered_file)
        for row in reader:
            print(f"\t\t{row}{ " " * 20 }", end="\r")
        print("\n")
    

    Dando a você algo como:

    Example Results:
            Total: 49901.74831312535
            Grouped Totals:
                    7.0: 0.5040226167253907
                    6.0: 0.49718272454103724
                    0.0: 0.49830374656445003
                    4.0: 0.5020429187707787
                    3.0: 0.4945115761171055
                    9.0: 0.4959816647030425
                    1.0: 0.49440301035945405
                    8.0: 0.5026981953484214
                    2.0: 0.49715019019186407
                    5.0: 0.5038847853189612
            Filtered:
                    ['99999', '0.26387763159374467', '7'] 
    
    • 0

relate perguntas

  • Como divido o loop for em 3 quadros de dados individuais?

  • Como verificar se todas as colunas flutuantes em um Pandas DataFrame são aproximadamente iguais ou próximas

  • Como funciona o "load_dataset", já que não está detectando arquivos de exemplo?

  • Por que a comparação de string pandas.eval() retorna False

  • Python tkinter/ ttkboostrap dateentry não funciona quando no estado somente leitura

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve