Je travaille avec la construction de stocks et donc de big dataframes. Je fais un échantillonnage de paramètres d'entrée pour 10000 stocks de 1000 bâtiments (donc si chaque bâtiment est une ligne dans un fichier csv, c'est environ 10000000 lignes à écrire dans les fichiers csv). Afin d'exécuter cela (sans obtenir MemoryError en Python) et de préparer les fichiers pour le programme de simulation, je devrai regrouper ces stocks en parties plus petites (au lieu d'un gros fichier), par exemple 100 actions de 1000 à la fois. Une idée comment faire cela?

J'ai préparé un petit exemple dans lequel j'ai un dataframe original dans lequel j'écrase une colonne dans une boucle. En fin de compte, j'empile tous les dataframes (générés dans la boucle) dans un big dataframe (qui contient alors x fois le dataframe original avec des changements ici et là. Au lieu de tout empiler dans un grand df et de l'enregistrer dans csv, je veux empilez-les par 100 actions à la fois.

Maintenant, j'empile tous les stocks dans un grand df et je le divise ensuite en morceaux avec une colonne supplémentaire 'ID'. Y a-t-il un moyen de le faire dans le processus (imaginez que j'ai besoin de 1000 ou 100000 stocks au total)? Calculer et empiler 100 actions -> les enregistrer dans csv -> calculer et empiler les 100 actions suivantes -> les enregistrer dans csv ...

Code essayé:

import pandas as pd

df_or = pd.DataFrame({"Case": [1,2,3,4,5,6],  
                         "A": [3,5,2,8,4,1],       
                         "B": [10,12,24,8,57,84]})

print(df_or)

total = []

for i in range(0,1000):
    df = df_or.copy()
    df.loc[:, 'A'] = df_or.loc[:, 'A'].mul(i)   
    df.loc[:, 'ID'] = df.loc[:,'Case'] + i*100000
    print(df)

    total.append(df)

total = pd.concat(total)
total = total.sort_values('ID')

for i in range(0, 10):

    stocks = total[((i) * 100 * 100000 <= total['ID']) & (total['ID'] <= (i + 1) * 100 * 100000)]

    stocks.to_csv('stack100_' + str(i) + '.csv', sep=',', index=False)


0
Matthi9000 31 août 2020 à 12:35

2 réponses

Meilleure réponse

Si vous avez moins d'un millier de fichiers à écrire, vous pouvez tous les ouvrir en même temps; à mesure que vous obtenez les données, écrivez chaque ligne dans le fichier approprié.

Vous devrez conserver les fichiers ouverts dans un dictionnaire ou similaire, afin que vous puissiez écrire chaque ligne dans le fichier correct et que vous puissiez tous les fermer à la fin.

Quelque chose comme:

from contextlib import ExitStack
import pandas as pd

df_or = pd.DataFrame({"Case": [1,2,3,4,5,6],
                         "A": [3,5,2,8,4,1],
                         "B": [10,12,24,8,57,84]})

with ExitStack() as stack:

    files = [
        stack.enter_context(open('stack100_' + str(j) + '.csv', 'w'))
        for j in range(0, 10)
    ]

    for i in range(0,1000):
        df = df_or.copy()
        df.loc[:, 'A'] = df_or.loc[:, 'A'].mul(i)
        df.loc[:, 'ID'] = df.loc[:,'Case'] + i*100000

        for j in range(0, 10):
            stocks = df[(
                (j) * 100 * 100000
                <= total['ID']) & (total['ID']
                <= (j + 1) * 100 * 100000
            )]
            stocks.to_csv(files[j], sep=',', index=False)

        del stocks, df
1
sabik 31 août 2020 à 12:15

Vous pouvez ouvrir un fichier en mode ajout et y écrire votre fichier.

import pandas as pd

df = pd.read_csv("abalone.csv")

with open("output.csv", 'a') as outf:
    df.to_csv(outf)

De cette façon, vous pouvez lire chaque fichier un par un, l'agréger et l'enregistrer dans un fichier. Un seul fichier est en mémoire à la fois.

Si vous n'analyserez les fichiers que par lots plus tard, je vous recommande de penser à les enregistrer dans ces lots à cette étape et vos fichiers seront plus faciles à gérer.

0
robertlayton 31 août 2020 à 09:40