#arrays #julia
Вопрос:
Допустим, у меня есть массив с 10 элементами:
arr = [1,2,3,4,5,6,7,8,9,10]
Затем я хочу определить функцию, которая принимает этот arr в качестве параметра для выполнения
вычисления, скажем, для этого примера вычисление представляет собой разницу средних, например:
Если N = 2 (это означает, что элементы arr последовательно группируются в группы размером 2):
results=[]
result_1 = 1 2/2 - 3 4/2
result_2 = 3 4/2 - 5 6/2
result_3 = 5 6/2 - 7 8/2
result_4 = 7 8/2 - 9 10/2
Результат будет:
results = [-2,-2,-2,-2]
Если N = 3 (это означает, что элементы arr последовательно группируются в группы размером 3):
results=[]
result_1 = 1 2 3/3 - 4 5 6/3
result_2 = 4 5 6/3 - 7 8 9/3
Результат будет:
results = [-3,-3]
Я хочу сделать это, определив две функции:
Функция 1 — Создает массивы, которые будут использоваться в качестве входных данных для 2-й функции:
Parameters: array, N
returns: k groups of arrays -> seems to be ((length(arr)/N) - 1)
Функция 2 — Будет функцией, которая получает массивы (2 на 2) и выполняет вычисления, в данном случае разницу средних.
Parameters: array1,array2....arr..arr..
returns: list of the results
Важное замечание
Моя идея состоит в том, чтобы применить эти функции к потоку данных, и вычислением будет PSI (индекс стабильности населения)
Итак, если в моем потоке 10 тыс. выборок и я устанавливаю для первой функции значение N = 1000, то выводом для второй функции будет 1 тыс. выборок следующие 1 тыс. выборок.
Процесс будет повторяться до конца потока данных
Я пытался сделать это на python (у меня уже есть готовый код PSI), но теперь я решил использовать для этого Julia, но я довольно новичок в Julia. Итак, если кто-нибудь может дать мне немного света, это будет очень полезно.
Комментарии:
1. Не
julia
программист, я могу ответить на это, но не вjulia
2. Я также ищу решение на python 😉 У меня есть готовый код PSI на Python.
Ответ №1:
В Julia, если у вас большой Vector
и вы хотите рассчитать некоторую статистику по группам из 3 элементов, вы могли бы сделать:
julia> a = collect(1:15); #creates a Vector [1,2,...,15]
julia> mean.(eachcol(reshape(a,3,length(a)÷3)))
5-element Vector{Float64}:
2.0
5.0
8.0
11.0
14.0
Обратите внимание, что оба reshape
и eachcol
не выделяются, поэтому данные не копируются в процессе.
Если длина a
не делится на 3
, вы можете обрезать ее перед изменением формы — чтобы избежать использования выделения view
для этого:
julia> a = collect(1:16);
julia> mean.(eachcol(reshape(view(a,1:(length(a)÷3)*3),3,length(a)÷3)))
5-element Vector{Float64}:
2.0
5.0
8.0
11.0
14.0
В зависимости от того, что вы на самом деле хотите сделать, вы также можете взглянуть на OnlineStats.jl
https://github.com/joshday/OnlineStats.jl
Ответ №2:
Ну, я использую JavaScript вместо Python, но это было бы то же самое в python…
Вам нужна chunks
функция, которая принимает array и chunk_size (N), скажем chunks([1,2,3,4], 2) -> [[1,2], [3,4]]
у нас есть метод sum, который добавляет все элементы в массив, sum([1,2]) -> 3
;
И JavaScript, и python поддерживают сопрограммирование, которое вы можете использовать для отложенной оценки, и вызываемую Generator
им функцию, этот тип функции может приостановить ее выполнение и может возобновиться по требованию! Это полезно для вычисления потока данных.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Javascript Doesn't support `chunks` method yet, So we need to create one...
Array.prototype.chunks = function* (N) {
let chunk = [];
for (let value of this) {
chunk.push(value)
if (chunk.length == N) {
yield chunk;
chunk = []
}
}
}
Array.prototype.sum = function () {
return this.reduce((a, b) => a b)
}
function* fnName(arr, N) {
let chunks = arr.chunks(N);
let a = chunks.next().value.sum();
for (let b of chunks) {
yield (a / N) - ((a = b.sum()) / N)
}
}
console.log([...fnName(arr, 2)])
console.log([...fnName(arr, 3)])
Комментарии:
1. Спасибо за объяснение. Я буду искать ключевые слова, которые вы сказали: фрагменты, сопрограммы, отложенная оценка. Это именно то, что я ищу xD