Джулия эквивалентна R replace()

В R есть функция replace(A, I, B), которая заменяет значения в A с индексами, заданными в I, на значения, заданные в B (B может быть скаляром). Как проще всего это сделать в Джулии?

Если вы посмотрите на источник replace, это единственный x[list] <- values. Так может A[I] = B?

GKi 12.07.2023 12:03

Да, он выполняет эту базовую функцию, но полезен для изменения переменной внутри такой функции, как f(replace()).

Mohammad 12.07.2023 13:48

Я добавил ответ ниже, который отвечает на ваш вопрос, просто создав новую функцию - не похоже, что есть встроенная функция, которую вы ищете.

Jonathan F. 12.07.2023 15:03

Итак, вы хотите что-то вроде replace в R, что не обновляет исходный вектор, а создает его копию, обновляет и возвращает измененную копию?

GKi 12.07.2023 23:06

Да, функция setindex(), представленная в приведенном ниже ответе @ahnlabb, работает, но не для скаляров.

Mohammad 13.07.2023 07:49
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
5
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Обычно это можно сделать с помощью присвоения по индексу:

array = [0,2,3]
array[1] = 1

# array is now [1,2,3]

Выше вы упомянули о необходимости функции, а также о возможности изменения нескольких индексов.

Это не функция в Base, но сделать это самостоятельно довольно сложно.

# Make a base function. Error catching is optional but included here.

function replace!(ar::Vector,i::Int,val)
    i<0&&error("Index must be non-negative")
    i>size(ar)[1]&&error("Index out of range")
    ar[i]=val
end

# Extend function for use on vector inputs

function replace!(ar::Vector,i::Vector{Int},val::Vector)
    size(i)!=size(val)&&error("Must have same number of indices and values")
    for j in 1:size(i)[1]
        replace!(ar,i[j],val[j])
    end
end

# Example Below

myArray = [9,9,9,9,9]

replace!(myArray,1,5)
# MyArray is now [5, 9, 9, 9, 9]

replace!(myArray,[2,3,4],[6,7,8])
# MyArray is now [5, 6, 7, 8, 9]

Это использует функцию множественной отправки Джулии, где функция может быть определена по-разному для разных входных параметров. Это основная функция, которая делает код очень понятным.

Имейте в виду, что если вы знаете, какие данные будет содержать входной массив, вы можете изменить это, чтобы расширить массив, если вы введете слишком высокий индекс, заполнив его некоторым значением-заполнителем, но это не было запрошено, поэтому это не было включено.

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

Соответствующая функция в Julia — setindex!:

setindex!(A, X, inds...)

Сохраните значения из массива X в некотором подмножестве A, как указано в inds. Синтаксис A[inds...] = X эквивалентен (setindex!(A, X, inds...); X).

Пример в РЕПЛ:

julia> A = [1,2,3,4,5]; I = [1,3]; B = [100, 101];

julia> setindex!(A, B, I);

julia> A
5-element Vector{Int64}:
 100
   2
 101
   4
   5

Обратите внимание, что setindex! изменяет аргумент. Мы можем использовать copy для выделения нового массива.

julia> setindex(A, X, inds...) = setindex!(copy(A), X, inds...)
setindex (generic function with 1 method)

julia> A = [1,2,3,4,5]; B = [100, 101]; I = [1,3];

julia> setindex(A, B, I)
5-element Vector{Int64}:
 100
   2
 101
   4
   5

julia> A
5-element Vector{Int64}:
 1
 2
 3
 4
 5

Этот ответ неверен. Это терпит неудачу, когда B является скалярным, как спрашивает OP. Имо, это также неидиоматично. Правильный и идиоматический ответ A[I] .= B

DNF 12.07.2023 23:35

Определенно согласен, что это не идиоматично. Я редко использовал/видел setindex! за исключением перегрузки оператора. Я интерпретирую вопрос и комментарий OP как вопрос о функции в стандартной библиотеке, которая является близким аналогом replace. Оба широковещательных assign и setindex! не могут полностью соответствовать, поскольку replace R не мутирует, но широковещательное присваивание возвращает материализованный массив вместо обновленного массива LHS. A[I] .= B в настоящее время анализируется как: broadcast!(identity, Broadcast.dotview(A, I), B) поэтому не соответствует функции в Base. Я расширю ответ и назову ваш идиомой.

ahnlabb 13.07.2023 00:47

Ответ прост:

A[I] .= B

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