2016-10-04 9 views
1

Мне интересно, почему индексирование DataArrays Джулии с значениями NA невозможно. Excuting пропущено ниже приводит к ошибке (NAException («не может индексировать массив с DataArray, содержащими значения NA»)):Индексирование данных данных Julia с включенными значениями NA

dm = data([1 4 7; 2 5 8; 3 1 9]) 
dm[dm .== 5] = NA 

dm[dm .< 3] = 1 #Error 
dm[(!isna(dm)) & (dm .< 3)] = 1 #Working 

Существует В решениях, чтобы игнорировать числовые апертуры в DataFrame с isna(), как ответил here , На первый взгляд он работает так, как следует, и игнорирование NA в DataFrames - это тот же подход, что и для DataArrays, потому что каждый столбец DataFrame является DataArray, указанным here. Но, по-моему, игнорирование отсутствующих значений с !isna() по каждому условию - не лучшее решение.

Для меня непонятно, почему модуль DataFrame генерирует ошибку, если NA включены. Если логический массив, необходимый для индексирования, имеет значения NA, эти значения должны преобразовываться в false, как MATLAB® или Pythons Pandas. В DataArray модули исходного кода (как показано ниже) в indexing.jl, существует явная функция бросить NAException:

# Indexing with NA throws an error 
function Base.to_index(A::DataArray) 
    any(A.na) && throw(NAException("cannot index an array with a DataArray containing NA values")) 
    Base.to_index(A.data) 
end 

Если изменить фрагмент кода, установив НС в ложь ...

# Indexing with NA throws an error 
function Base.to_index(A::DataArray) 
    A[A.na] = false 
    any(A.na) && throw(NAException("cannot index an array with a DataArray containing NA values")) 
    Base.to_index(A.data) 
end 

... dm[dm .< 3] = 1 работает так, как должно (например, в MATLAB® или Pandas).

Для меня нет смысла автоматически бросать ошибку, если NA включены в индексирование. В этом случае должен быть параметр, создающий DataArray, чтобы пользователь мог выбрать, игнорируются ли NA. Есть две существенные причины: с одной стороны, это не очень приятно писать и читать код, когда у вас есть формулы с большим количеством индексирования и значениями NA (например, вычисление моделей метеорологической сетки), а с другой стороны, наблюдается заметная потеря производительность, что это timetest показывает:

@timeit dm[(!isna(dm)) & (dm .< 3)] = 1 #14.55 µs per loop 
@timeit dm[dm .< 3] = 1 #754.79 ns per loop 

что является причиной того, что разработчики делают использование этого исключения, и есть еще более простой подход, как !isna() за игнорирование NA-й в DataArrays?

ответ

5

Предположим, у вас есть три кролика. Вы хотите поместить женского кролика (ов) в отдельную клетку у самцов. Вы смотрите на первого кролика, и он выглядит как мужчина, поэтому вы оставите его там, где он есть. Вы смотрите на второго кролика, и это похоже на женщину, поэтому вы перемещаете ее в отдельную клетку. Вы не можете хорошо взглянуть на третьего кролика. Что вы должны сделать?

Это зависит. Может быть, ты в порядке, оставив кролика неизвестного пола. Но если вы отделите кроликов, потому что вы не хотите, чтобы они делали кроликов-младенцев, вам может потребоваться, чтобы ваше программное обеспечение для анализа сообщило вам, что оно не знает пола третьего кролика.

Подобные ситуации возникают часто при анализе данных. В наиболее патологических случаях данные отсутствуют систематически, а не случайным образом. Если бы вы исследовали группу людей о том, как выглядят пушистые кролики и нужно ли их больше есть, вы можете сравнить mean(fluffiness[should_be_eaten_more]) и mean(fluffiness[!should_be_eaten_more]). Но, если люди, которые действительно любят кроликов, возмущены тем, что вы говорите о том, чтобы есть их вообще, они могут оставить этот второй вопрос пустым. Если вы проигнорируете это, вы будете недооценивать средний рейтинг пушистости среди людей, которые не думают, что кроликов следует есть больше, что было бы серьезной ошибкой. Вот почему fluffiness[!should_be_eaten_more] выдает ошибку, если отсутствуют значения: Это знак того, что все, что вы пытаетесь сделать с вашими данными, может не дать правильных результатов.Эта ситуация достаточно плоха, что люди пишут все бумаги об этом, например. this one.

Достаточно о кроликах. Возможно, что когда-либо должен быть (и может быть когда-нибудь) более краткий способ сбросить/сохранить все пропущенные значения при индексировании, но он всегда будет явным, а не подразумеваемым по причине, описанной выше. Что касается производительности, в то время как наблюдается замедление для isna(x) & (x < 3) против x < 3, накладные расходы на многократное индексирование в массив также высоки, и DataArrays добавляет дополнительные накладные расходы поверх этого. Относительные накладные расходы уменьшаются по мере увеличения массива. Если это узкое место в коде, лучше всего написать его по-другому.