2016-08-24 10 views
2

Я объединять файлы в 4 папки. В пределах этих 4 папок я объединяю 80 .dbf файлов, каждый из которых составляет 35 мегабайт. Я использую следующий код:Ошибка памяти, даже если оперативная память бесплатна

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) 

почти сразу после запуска кода я получаю эту ошибку:

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 

, но только 30% моей памяти используется, что в значительной степени базовая.

EDIT:

Я выбрал только 2 файлов и попытался слияния с помощью:

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

и до сих пор получаю ошибку памяти, что-то странное происходит.

Когда я запускаю то же самое в 32-битном Anaconda я получаю ValueError: negative dimensions are not allowed

EDIT:

Вся проблема вытекает из решения дают здесь: Value Error: negative dimensions are not allowed when merging

+0

Пробуйте использовать последние две строки из обоих циклов 'for'. В вашем предыдущем коде, в последней итерации, вы присоединяетесь к своему первому набору данных столько раз, сколько количество файлов, которые у вас есть ... – ragesz

+0

Извините, но все же довольно новый для python, по 'out' вы имеете в виду, что последние две строки должны быть выровнены с моим первым 'if'? –

ответ

2

EDITED на основе комментариев :

Попробуйте это (достаточно использовать только один оператор if с логическим and):

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

Мне любопытно, почему исходный случай привел к ошибке памяти, а ответа нет? – dartdog

+0

Я думаю, что они объяснили в комментарии к исходному сообщению, он заставляет его присоединяться столько раз, сколько количество файлов, а не только один раз в папке –

+0

, ошибка памяти все еще возникала, для этого потребовалось всего один час, но на этот раз мой баран был действительно полным. –