我也注意到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做的就是从对象系列中获取价值。
我正在尝试使用此mapRows函数来执行基于行的处理并生成对象序列,然后mapRows可以创建具有相同行键的新帧。该过程必须基于行,因为列值需要根据其自身的值和相邻值进行更新。
计算不能直接使用列到列,因为计算会根据行值进行更改。
欣赏任何建议
更新
自从发布原始问题以来,我已经在C#中使用了Deedle。令我惊讶的是,基于行的计算在C#中非常容易,并且C#Frame.rows函数处理缺失值的方式与F#mapRows函数非常不同。以下是我用来尝试和实现逻辑的一个非常基本的例子。它可能对搜索类似应用程序的人有用:
需要注意的事项是: 1.行的功能并没有删除行,而两列都是&#39;价值缺失 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();
}
}
}
答案 0 :(得分:2)
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