Python: вычисление процентилей в netcdf, превышение памяти. Есть ли более эффективный метод? - PullRequest
0 голосов
/ 20 апреля 2020

Я читаю два файла netcdf. Первый файл содержит трехмерное поле с плавающей запятой, а второй содержит трехмерное целочисленное поле. Проценты вычисляются, когда для каждого целочисленного значения (исключая 0) во втором файле в пространстве-времени накладывается переменная в первом файле. Проценты сохраняются для каждого целочисленного значения и записываются в текстовый файл, где каждая строка является значением целого числа во втором файле.

Работа с меньшими подмножествами данных для целей тестирования не привела к проблемам с кодом , Однако работа с полным набором данных теперь приводит к ошибкам выделения памяти (int64). Ясно, что набор данных слишком велик, но, поскольку это процентили, он должен вычислять их по всему набору данных, хранить и записывать эти значения построчно.

Я помню, pandas имеет некоторые утечки памяти и словари также очень интенсивно используют память. Возможно, есть лучшие методы для использования в python? Или другой язык? Обратите внимание, я не могу использовать параллельную версию python.

from pylab import *
import numpy as np
import pandas as pd
import xarray as xr
import netCDF4

# Percentile definitions
def q10(x):
     return x.quantile(0.1)
def q90(x):
     return x.quantile(0.9)

# Open data with xarray
dt = xr.open_mfdataset(['p_in.nc', 'i_in.nc'], combine='by_coords', autoclose=T)

# Convert to data frame
dtdf = dt.to_dataframe()

# Compute percentiles, grouped by i in i_in
dp = {'p': [q10]} # dictionary
p = dtdf.groupby('i_bin').agg(dp)
p.columns = ['_'.join(col) for col in p.columns.values]
p_10 = p.loc[1:, 'pr_q10'] # don't need the first value for i=0

dp = {'p': [q90]} # dictionary
p = dtdf.groupby('i_bin').agg(dp)
p.columns = ['_'.join(col) for col in p.columns.values]
p_90 = p.loc[1:, 'pr_q90'] # don't need the first value for i=0

# Write data to ascii file
columns = [p_10, p_90]
#columns = [p_10, p_90]
data = zip(*columns)
separator = '\t'
with open('output.txt','w') as fout:
    for line in data:
        fout.write( separator.join( map(str,line) ) )
        fout.write('\n')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...