Случайным образом маскировать/устанавливать nan x% точек данных в огромном массиве xarray.DataArray

У меня огромный (~ 2 миллиарда точек данных) xarray.DataArray. Я хотел бы случайным образом удалить (маскировать или заменить на np.nan) заданный процент данных, где вероятность выбора каждой точки данных для удаления/маскирования одинакова по всем координатам. Я могу преобразовать массив в numpy.array, но я бы предпочел сохранить его в фрагментах dask для скорости.

мои данные выглядят так:

>> data
<xarray.DataArray 'stack-820860ba63bd07adc355885d96354267' (variable: 8, time: 228, latitude: 721, longitude: 1440)>
dask.array<stack, shape=(8, 228, 721, 1440), dtype=float64, chunksize=(1, 6, 721, 1440)>
Coordinates:
* latitude   (latitude) float32 90.0 89.75 89.5 89.25 89.0 88.75 88.5 ...
* variable   (variable) <U5 u'fal' u'swvl1' u'swvl3' u'e' u'swvl2' u'es' 
* longitude  (longitude) float32 0.0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 
* time       (time) datetime64[ns] 2000-01-01 2000-02-01 2000-03-01 ...

я определил

frac_missing = 0.2
k = int(frac_missing*data.size)

это то, что я уже пробовал:

  • это решение работает с np.ndindex, но объект np.ndindex преобразуется в список, что очень медленно. Я попытался обойти преобразование и просто выполнить итерацию по объекту np.ndindex, как описано здесь и здесь, но итерация по всему итератору медленная для ~ 2 миллиардов точек данных.
  • np.random.choice(data.stack(newdim=('latitude','variable','longitude','time')),k,replace=False) возвращает желаемое подмножество точек данных, но не устанавливает для них значение nan

Ожидаемым результатом будет xarray.DataArray с заданным процентом точек данных, либо установленным в np.nan, либо замаскированным, предпочтительно в той же форме и в тех же фрагментах данных.

data[np.random.rand(*data.shape) < frac_missing] = np.nan работает? Я не использовал dask, но так вы бы сделали это в numpy.

user545424 22.05.2019 19:39

@ user545424 это элегантное решение, однако оно создает numpy.array того же размера, что и data, что слишком медленно

climachine 23.05.2019 16:30
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
2
2
187
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предложение пользователь545424 — отличное начало. Чтобы не сталкиваться с проблемами памяти, вы можете поместить ее в небольшую пользовательскую функцию и отобразить ее на DataArray с помощью метода apply_ufunc.

import xarray as xr
import numpy as np

testdata = xr.DataArray(np.empty((100,1000,1000)), dims=['x','y','z'])

def set_random_fraction_to_nan(data):
    data[np.random.rand(*data.shape) < .8]=np.nan
    return data

# Set 80% of data randomly to nan
testdata = xr.apply_ufunc(set_random_fraction_to_nan, testdata, input_core_dims=[['x','y','z']],output_core_dims=[['x','y','z']], dask='parallelized')

Дополнительные пояснения по переносу пользовательских функций для работы с xarray см. в статье здесь..

когда testdata используется для нескольких окончательных продуктов данных, которые только лениво оцениваются в конце, их модели отсутствия не согласуются, хотя команда была выполнена только один раз. Это довольно неожиданное поведение, его можно решить с помощью np.random.seed(0) в определении функции (см. мое редактирование).

climachine 17.08.2019 13:26

Другие вопросы по теме