Как я могу преобразовать pd.Series в xr.DataArray на основе dask? - PullRequest
1 голос
/ 31 мая 2019

У меня есть данные как pd.Series с pd.MultiIndex:

  • 1–8 измерений (уровни индекса),
  • 1–500 меток вдоль каждого измерения,
  • ~ 5–20 миллионов элементов в декартовом произведении этих меток, но
  • заполнено менее чем на 1%.

Я хотел бы преобразовать эти данные в xr.DataArray.

Вот некоторый пример кода, который создает pd.Series с 377 элементами из возможных 73 984 365 - всего 0,00051% заполнения.

from itertools import zip_longest

import numpy as np
import pandas as pd

# Dimensions and their lengths
dims = 'abcdef'
sizes = [1, 5, 21, 21, 89, 377]

# Names like f_000 … f_376 along each dimension
coords = []
for d, N in zip(dims, sizes):
    coords.append([f'{d}_{i:03d}' for i in range(N)])

def make_values():
    """Make a DataFrame containing each label in *coords* at least once."""
    values = list(zip_longest(*coords, np.random.rand(max(sizes))))
    result = pd.DataFrame(values, columns=list(dims) + ['value']) \
               .ffill() \
               .set_index(list(dims))
    return result

data = make_values()

Невозможно xr.DataArray.from_series(data), а затем .chunk(…) результат, потому что шаг создания (с использованием xr.Dataset.from_dataframe() внутри) создает полный декартово произведение и производит MemoryError.

Я пробовал:

  1. Предварительное выделение памяти с использованием xr.DataArray(dask.array.full(fill_value=None, shape=sizes), …) - но это создает объект только для чтения, и я не могу присвоить ему значения из data.
  2. Запись в файл, что-то вроде:

    import xarray as xr
    
    store = pd.HDFStore('temp.h5')
    store.put('foo', data)
    
    xr.open_dataset('temp.h5', chunks={})  # or with engine='h5netcdf'
    

    … но это вызывает исключения.

Есть ли способ сделать это, если не создавать вручную файл в одном из форматов, распознаваемых xarray?

...