2016-08-24 1 views
2

Je fusionne les fichiers dans 4 dossiers. Dans ces 4 dossiers, je fusionne 80 fichiers .dbf dont chacun est de 35 mégaoctets. Je suis en utilisant le code suivant:Erreur de mémoire même si la RAM est libre

import os 
import pandas as pd 
from simpledbf import Dbf5 

list1=[] 
folders=r'F:\dbf_tables' 
out=r'F:\merged' 
if not os.path.isdir(out): 
    os.mkdir(out) 
for folder in os.listdir(folders): 
    if not os.path.isdir(os.path.join(out,folder)): 
     os.mkdir(os.path.join(out,folder)) 
    for f in os.listdir(os.path.join(folders,folder)): 
     if '.xml' not in f: 
      if '.cpg' not in f: 
       table=Dbf5(os.path.join(folders,folder,f)) 
       df=table.to_dataframe() 
       list1.append(df) 
       dfs = reduce(lambda left,right: pd.merge(left,right,on=['POINTID'],how='outer',),list1) 
       dfs.to_csv(os.path.join(out,folder,'combined.csv'), index=False) 

presque immédiatement après l'exécution du code que je reçois cette erreur:

Traceback (most recent call last): 

    File "<ipython-input-1-77eb6fd0cda7>", line 1, in <module> 
    runfile('F:/python codes/prelim_codes/raster_to_point.py', wdir='F:/python codes/prelim_codes') 

    File "C:\Users\spotter\AppData\Local\Continuum\Anaconda_64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 714, in runfile 
    execfile(filename, namespace) 

    File "C:\Users\spotter\AppData\Local\Continuum\Anaconda_64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 74, in execfile 
    exec(compile(scripttext, filename, 'exec'), glob, loc) 

    File "F:/python codes/prelim_codes/raster_to_point.py", line 66, in <module> 
    dfs = reduce(lambda left,right: pd.merge(left,right,on=['POINTID'],how='outer',),list1) 

    File "F:/python codes/prelim_codes/raster_to_point.py", line 66, in <lambda> 
    dfs = reduce(lambda left,right: pd.merge(left,right,on=['POINTID'],how='outer',),list1) 

    File "C:\Users\spotter\AppData\Local\Continuum\Anaconda_64\lib\site-packages\pandas\tools\merge.py", line 39, in merge 
    return op.get_result() 

    File "C:\Users\spotter\AppData\Local\Continuum\Anaconda_64\lib\site-packages\pandas\tools\merge.py", line 217, in get_result 
    join_index, left_indexer, right_indexer = self._get_join_info() 

    File "C:\Users\spotter\AppData\Local\Continuum\Anaconda_64\lib\site-packages\pandas\tools\merge.py", line 353, in _get_join_info 
    sort=self.sort, how=self.how) 

    File "C:\Users\spotter\AppData\Local\Continuum\Anaconda_64\lib\site-packages\pandas\tools\merge.py", line 559, in _get_join_indexers 
    return join_func(lkey, rkey, count, **kwargs) 

    File "pandas\src\join.pyx", line 160, in pandas.algos.full_outer_join (pandas\algos.c:61256) 

MemoryError 

mais seulement 30% de ma mémoire est utilisée, ce qui est à peu près la ligne de base.

EDIT:

Je choisis seulement 2 fichiers et essayé la fusion en utilisant:

merge=pd.merge(df1,df2, on=['POINTID'], how='outer') 

et toujours obtenir une erreur de mémoire, quelque chose de bizarre se passe.

Quand je lance la même chose en 32 bits Anaconda Je reçois ValueError: negative dimensions are not allowed

EDIT:

Tout le problème provient de la solution donne ici: Value Error: negative dimensions are not allowed when merging

+0

Essayez d'utiliser vos deux dernières lignes des deux boucles 'for'. Au code ci-dessus, à la dernière itération, vous joignez votre premier ensemble de données autant de fois que le nombre de fichiers que vous avez ... – ragesz

+0

Désolé mais toujours nouveau pour python, par 'out' voulez-vous dire que les deux dernières lignes devraient être alignées avec mon premier «si»? –

Répondre

2

ÉDITÉ basé sur le commentaire :

Essayez ceci (il suffit d'utiliser une seule instruction if avec logique and conditions):

import os 
import pandas as pd 
from simpledbf import Dbf5 

folders = r'F:\dbf_tables' 
out = r'F:\merged' 

if not os.path.isdir(out): 
    os.mkdir(out) 

for folder in os.listdir(folders): 
    if not os.path.isdir(os.path.join(out, folder)): 
     os.mkdir(os.path.join(out, folder)) 

    # Initialize empty dataframe by folders 
    dfs = pd.DataFrame(columns=['POINTID']) 

    for f in os.listdir(os.path.join(folders, folder)): 
     if ('.xml' not in f) and ('.cpg' not in f): 
      table = Dbf5(os.path.join(folders, folder, f)) 
      df = table.to_dataframe() 

      # Merge actual dataframe to result dataframe 
      dfs = dfs.merge(df, on=['POINTID'], how='outer') 

    # Save results by folder 
    dfs.to_csv(os.path.join(out, folder, 'combined.csv'), index=False) 
+0

Je suis curieux de savoir pourquoi le cas initial a entraîné une erreur de mémoire et la réponse ne fonctionne pas? – dartdog

+0

Je pense qu'ils ont expliqué dans un commentaire à l'article original, Il le fait rejoindre autant de fois que le nombre de fichiers, plutôt qu'une seule fois par dossier –

+0

effectivement, l'erreur de mémoire est encore apparu, il a fallu juste une heure pour le faire, mais cette fois, mon bélier était plein. –