Deedle Frame.mapRows, как правильно его использовать и как правильно построить серию объектов
Я также заметил кое-что странное в функции Deedle mapRows, которую я не могу объяснить:
let col1 = Series.ofObservations[1=>10.0;2=>System.Double.NaN;3=>System.Double.NaN;4=>10.0;5=>System.Double.NaN;6=>10.0; ]
let col2 = Series.ofObservations[1=>9.0;2=>5.5;3=>System.Double.NaN;4=>9.0;5=>System.Double.NaN;6=>9.0; ]
let f1 = Frame.ofColumns [ "c1" => col1; "c2" => col2 ]
let f2 = f1 |> Frame.mapRows (fun k r -> r) |> Frame.ofRows
let f3 = f1 |> Frame.mapRows (fun k r -> let x = r.Get("c1");
let y = r.Get("c2");
r) |> Frame.ofRows
val f1 : Frame<int,string> =
c1 c2
1 -> 10 9
2 -> <missing> 5.5
3 -> <missing> <missing>
4 -> 10 9
5 -> <missing> <missing>
6 -> 10 9
val f2 : Frame<int,string> =
c1 c2
1 -> 10 9
2 -> <missing> 5.5
3 -> <missing> <missing>
4 -> 10 9
5 -> <missing> <missing>
6 -> 10 9
val f3 : Frame<int,string> =
c1 c2
1 -> 10 9
2 -> <missing> <missing>
3 -> <missing> <missing>
4 -> 10 9
5 -> <missing> <missing>
6 -> 10 9
Как f3 может иметь значение, отличное от f2? все, что я сделал с помощью f3, это чтобы получить значение от obejectseries.
Я пытаюсь использовать эту функцию mapRows, чтобы сделать процесс на основе строк и произвести серию объектов, тогда mapRows может создать новый фрейм с теми же ключами строки. Процесс должен основываться на строках, так как значение столбца должно обновляться на основе его собственного значения и соседнего значения.
Вычисление не может быть выполнено, используя столбец к столбцу напрямую, так как вычисление изменяется на основе значения строки.
Цени любой совет
Обновить
Так как оригинальный вопрос был опубликован, я с тех пор использовал Deedle в C#. К моему удивлению, вычисления на основе строк очень просты в C#, и способ, которым функция C# Frame.rows обрабатывает пропущенные значения, сильно отличается от функции F# mapRows. Ниже приведен очень простой пример, который я использовал, чтобы попытаться проверить правильность логики. это может быть полезно любому, кто ищет подобное приложение:
На что следует обратить внимание: 1. Функция "строки" не удаляла строку, в то время как значения обоих столбцов отсутствуют. 2. Функция среднего значения достаточно умна для вычисления среднего значения на основе доступной точки данных.
using System.Text;
using System.Threading.Tasks;
using Deedle;
namespace TestDeedleRowProcessWithMissingValues
{
class Program
{
static void Main(string[] args)
{
var s1 = new SeriesBuilder<DateTime, double>(){
{DateTime.Today.Date.AddDays(-5),10.0},
{DateTime.Today.Date.AddDays(-4),9.0},
{DateTime.Today.Date.AddDays(-3),8.0},
{DateTime.Today.Date.AddDays(-2),double.NaN},
{DateTime.Today.Date.AddDays(-1),6.0},
{DateTime.Today.Date.AddDays(-0),5.0}
}.Series;
var s2 = new SeriesBuilder<DateTime, double>(){
{DateTime.Today.Date.AddDays(-5),10.0},
{DateTime.Today.Date.AddDays(-4),double.NaN},
{DateTime.Today.Date.AddDays(-3),8.0},
{DateTime.Today.Date.AddDays(-2),double.NaN},
{DateTime.Today.Date.AddDays(-1),6.0}
}.Series;
var f = Frame.FromColumns(new KeyValuePair<string, Series<DateTime, double>>[] {
KeyValue.Create("s1",s1),
KeyValue.Create("s2",s2)
});
s1.Print();
f.Print();
f.Rows.Select(kvp => kvp.Value).Print();
// 29/05/2015 12:00:00 AM -> series [ s1 => 10; s2 => 10]
// 30/05/2015 12:00:00 AM -> series [ s1 => 9; s2 => <missing>]
// 31/05/2015 12:00:00 AM -> series [ s1 => 8; s2 => 8]
// 1/06/2015 12:00:00 AM -> series [ s1 => <missing>; s2 => <missing>]
// 2/06/2015 12:00:00 AM -> series [ s1 => 6; s2 => 6]
// 3/06/2015 12:00:00 AM -> series [ s1 => 5; s2 => <missing>]
f.Rows.Select(kvp => kvp.Value.As<double>().Mean()).Print();
// 29/05/2015 12:00:00 AM -> 10
// 30/05/2015 12:00:00 AM -> 9
// 31/05/2015 12:00:00 AM -> 8
// 1/06/2015 12:00:00 AM -> <missing>
// 2/06/2015 12:00:00 AM -> 6
// 3/06/2015 12:00:00 AM -> 5
//Console.ReadLine();
}
}
}
1 ответ
Причина по которой f3
отличается от того, как mapRows
обрабатывает пропущенные значения.
Когда вы получаете доступ к значению с помощью r.Get("C1")
вы либо получаете значение, либо вы получаете ValueMissingException
, mapRows
Функция обрабатывает это исключение и помечает всю строку как отсутствующую. Если вы напишите просто:
let f3 = f1 |> Frame.mapRows (fun k r ->
let x = r.Get("c1");
let y = r.Get("c2");
r)
Тогда результат будет:
1 -> series [ c1 => 10; c2 => 9]
2 -> <missing>
3 -> <missing>
4 -> series [ c1 => 10; c2 => 9]
5 -> <missing>
6 -> series [ c1 => 10; c2 => 9]
Если вы хотите написать функцию, которая возвращает фрейм как он есть (чтение данных из исходных строк и создание новых строк), вы можете сделать что-то вроде:
f1
|> Frame.mapRows (fun k r ->
[ "X" => OptionalValue.asOption(r.TryGet("c1"));
"Y" => OptionalValue.asOption(r.TryGet("c2")) ]
|> Series.ofOptionalObservations )
|> Frame.ofRows