Data Frame - согласованность порядка при преобразовании в матрицу
У меня есть дидл Frame<DateTime,string>
, Столбцы содержат float
значения и являются плотными (без пропущенных значений).
Мне нужно построить фрейм данных из string []
а потом:
- Построить 2D
Matrix
со всеми данными - Построить серию
Series<DateTime,Matrix<float,CpuLib>>
, сворачивая ряды в1xn
матрица
В моем случае я экспериментирую с FCore от StatFactory, но в будущем я могу использовать другую библиотеку линейной алгебры.
Меня беспокоит то, что мне нужно убедиться, что порядок строк и столбцов в процессе не изменился.
Построение фрейма данных
Я получаю данные, используя следующее. Я заметил, что порядок столбцов отличается от первоначального списка тикеров. Это почему? Будет ли использование Array.Parallel.Map
изменить порядок?
/// get the selected tickers in a DataFrame from a DataContext
let fetchTickers tickers joinKind =
let getTicker ticker =
query {
for row in db.PriceBarsDay do
where (row.Ticker = ticker)
select row }
|> Seq.map (fun row -> row.DateTime, float row.Close)
|> dict
tickers
|> Array.map (fun ticker -> getTicker ticker) // returns a dict(DateTime, ClosePrice)
|> Array.map (fun dictionary -> Series(dictionary))
|> Array.map2 (fun ticker series -> [ticker => series] |> frame ) tickers
|> Array.reduce (fun accumFrame frame -> accumFrame.Join(frame, joinKind))
Кадр данных в 2D матрицу
Для построения матрицы я использую код ниже. Отображение на массив имен столбцов (selectedCols
) гарантирует, что порядок столбцов не смещается. Я запускаю модульные тесты в порядке строк, используя Array.Map
и все выглядит хорошо, но я хотел бы знать,
- если в библиотеке есть проверка согласованности, которая может предотвратить возникновение проблемы?
- Я полагаю
Array.Parallel.map
сохранит порядок столбцов.
Вот код:
/// Build a matrix
let buildMatrix selectedCols (frame: Frame<DateTime, String>) =
let matrix =
selectedCols
|> Array.map (fun colname -> frame.GetSeries(colname))
|> Array.map (fun serie -> Series.values serie)
|> Array.map (fun aSeq -> Seq.map unbox<float> aSeq)
|> Array.map (fun aSeq -> Matrix(aSeq) )
|> Array.reduce (fun acc matrix -> acc .| matrix)
matrix.T
От кадра данных к временному ряду матриц строк
Я строю временные ряды матриц строк с помощью кода ниже.
- Хранение данных в Серии должно гарантировать, что порядок строк сохраняется.
- Как я могу отфильтровать столбцы и убедиться, что порядок столбцов точно такой же, как в массиве имен столбцов, передаваемых в функцию?
Вот код:
// Time series of row matrices - it'll be used to run a simulation
let timeSeriesOfMatrix frame =
frame
|> Frame.filterRows (fun day target -> day >= startKalman)
|> Frame.mapRowValues ( fun row -> row.Values |> Seq.map unbox<float> )
|> Series.mapValues( fun row -> Matrix(row) )
Большое спасибо.
PS: я сохранил все три сценария вместе, потому что я считаю, что три приведенных выше примера лучше помогут другим пользователям и мне понять, как работает библиотека, а не обсуждать каждый отдельный случай отдельно.
1 ответ
Чтобы ответить на первую часть, порядок меняется, потому что вы объединяете упорядоченные кадры (содержащие только одну серию), и конструкция кадра сохраняет порядок в этом случае. Вы, вероятно, можете заменить последние две строки, используя только Frame.ofColumns
вместо использования явного соединения (это всегда будет делать внешнее соединение, но если вам нужно внутреннее соединение, вы можете использовать Frame.dropSparseRows
отбросить пропущенные значения).
Во втором примере все выглядит хорошо - вы можете сэкономить некоторую работу, напрямую получая данные в виде числа с плавающей запятой;
frame.GetSeries<float>(colname).Values
Третий пример также выглядит хорошо, и вы можете сделать его немного короче:
row.As<float>().Values