ML - рефакторинг Clone, IsValid
This commit is contained in:
parent
9cf33b094c
commit
94927c73e1
|
|
@ -1,6 +1,11 @@
|
||||||
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
// =============================================================
|
||||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
// СТАТИСТИЧЕСКОЕ СОГЛАШЕНИЕ (DataFrame)
|
||||||
// DataFrameABC v.1.1
|
//
|
||||||
|
// Используется выборочная дисперсия (деление на n - 1),
|
||||||
|
// как принято в описательной статистике.
|
||||||
|
//
|
||||||
|
// См. статистическую политику в модуле MLABC.
|
||||||
|
// =============================================================
|
||||||
|
|
||||||
/// Стандартный модуль для работы с табличными данными (датасетами)
|
/// Стандартный модуль для работы с табличными данными (датасетами)
|
||||||
/// !! DataFrame module for tabular data processing
|
/// !! DataFrame module for tabular data processing
|
||||||
|
|
@ -95,7 +100,6 @@ type
|
||||||
function GetColumn(name: string): Column;
|
function GetColumn(name: string): Column;
|
||||||
|
|
||||||
function CloneWithCopiedColumns: DataFrame;
|
function CloneWithCopiedColumns: DataFrame;
|
||||||
static procedure EnsureValidArray(var valid: array of boolean; rowCount, filledCount: integer);
|
|
||||||
public
|
public
|
||||||
/// Создает пустой DataFrame
|
/// Создает пустой DataFrame
|
||||||
constructor Create;
|
constructor Create;
|
||||||
|
|
@ -692,17 +696,17 @@ begin
|
||||||
if li >= 0 then
|
if li >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := leftCol.Data[li];
|
data[i] := leftCol.Data[li];
|
||||||
valid[i] := if leftCol.IsValid = nil then true else leftCol.IsValid[li];
|
valid[i] := leftCol.IsValid[li];
|
||||||
end
|
end
|
||||||
else if ri >= 0 then
|
else if ri >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := rightCol.Data[ri];
|
data[i] := rightCol.Data[ri];
|
||||||
valid[i] := if rightCol.IsValid = nil then true else rightCol.IsValid[ri];
|
valid[i] := rightCol.IsValid[ri];
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
data[i] := 0;
|
data[i] := 0;
|
||||||
valid[i] := false;
|
valid[i] := False;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -729,17 +733,17 @@ begin
|
||||||
if li >= 0 then
|
if li >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := leftCol.Data[li];
|
data[i] := leftCol.Data[li];
|
||||||
valid[i] := if leftCol.IsValid = nil then true else leftCol.IsValid[li];
|
valid[i] := leftCol.IsValid[li];
|
||||||
end
|
end
|
||||||
else if ri >= 0 then
|
else if ri >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := rightCol.Data[ri];
|
data[i] := rightCol.Data[ri];
|
||||||
valid[i] := if rightCol.IsValid = nil then true else rightCol.IsValid[ri];
|
valid[i] := rightCol.IsValid[ri];
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
data[i] := 0.0;
|
data[i] := 0.0;
|
||||||
valid[i] := false;
|
valid[i] := False;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -766,17 +770,17 @@ begin
|
||||||
if li >= 0 then
|
if li >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := leftCol.Data[li];
|
data[i] := leftCol.Data[li];
|
||||||
valid[i] := if leftCol.IsValid = nil then true else leftCol.IsValid[li];
|
valid[i] := leftCol.IsValid[li];
|
||||||
end
|
end
|
||||||
else if ri >= 0 then
|
else if ri >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := rightCol.Data[ri];
|
data[i] := rightCol.Data[ri];
|
||||||
valid[i] := if rightCol.IsValid = nil then true else rightCol.IsValid[ri];
|
valid[i] := rightCol.IsValid[ri];
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
data[i] := '';
|
data[i] := '';
|
||||||
valid[i] := false;
|
valid[i] := False;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -803,12 +807,12 @@ begin
|
||||||
if li >= 0 then
|
if li >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := leftCol.Data[li];
|
data[i] := leftCol.Data[li];
|
||||||
valid[i] := if leftCol.IsValid = nil then true else leftCol.IsValid[li];
|
valid[i] := leftCol.IsValid[li];
|
||||||
end
|
end
|
||||||
else if ri >= 0 then
|
else if ri >= 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := rightCol.Data[ri];
|
data[i] := rightCol.Data[ri];
|
||||||
valid[i] := if rightCol.IsValid = nil then true else rightCol.IsValid[ri];
|
valid[i] := rightCol.IsValid[ri];
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
|
@ -838,12 +842,12 @@ begin
|
||||||
if j < 0 then
|
if j < 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := 0;
|
data[i] := 0;
|
||||||
valid[i] := false;
|
valid[i] := False;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
data[i] := src.Data[j];
|
data[i] := src.Data[j];
|
||||||
valid[i] := if src.IsValid = nil then true else src.IsValid[j];
|
valid[i] := src.IsValid[j];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -868,12 +872,12 @@ begin
|
||||||
if j < 0 then
|
if j < 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := 0.0;
|
data[i] := 0.0;
|
||||||
valid[i] := false;
|
valid[i] := False;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
data[i] := src.Data[j];
|
data[i] := src.Data[j];
|
||||||
valid[i] := if src.IsValid = nil then true else src.IsValid[j];
|
valid[i] := src.IsValid[j];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -898,12 +902,12 @@ begin
|
||||||
if j < 0 then
|
if j < 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := '';
|
data[i] := '';
|
||||||
valid[i] := false;
|
valid[i] := False;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
data[i] := src.Data[j];
|
data[i] := src.Data[j];
|
||||||
valid[i] := if src.IsValid = nil then true else src.IsValid[j];
|
valid[i] := src.IsValid[j];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -927,13 +931,13 @@ begin
|
||||||
|
|
||||||
if j < 0 then
|
if j < 0 then
|
||||||
begin
|
begin
|
||||||
data[i] := false;
|
data[i] := False;
|
||||||
valid[i] := false;
|
valid[i] := False;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
data[i] := src.Data[j];
|
data[i] := src.Data[j];
|
||||||
valid[i] := if src.IsValid = nil then true else src.IsValid[j];
|
valid[i] := src.IsValid[j];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -2223,21 +2227,10 @@ end;
|
||||||
|
|
||||||
procedure DataFrame.AddIntColumn(name: string; data: array of integer; valid: array of boolean);
|
procedure DataFrame.AddIntColumn(name: string; data: array of integer; valid: array of boolean);
|
||||||
begin
|
begin
|
||||||
if (columns.Count > 0) and (data.Length <> RowCount) then
|
if (columns.Count > 0) and (Length(data) <> RowCount) then
|
||||||
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
||||||
|
|
||||||
var c := new IntColumn;
|
var c := new IntColumn(name, data, valid);
|
||||||
c.Info := new ColumnInfo(name, ctInt);
|
|
||||||
c.Data := data;
|
|
||||||
|
|
||||||
if valid = nil then
|
|
||||||
c.IsValid := [True] * data.Length
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if valid.Length <> data.Length then
|
|
||||||
DimensionError(ER_COLUMN_VALID_LENGTH_MISMATCH);
|
|
||||||
c.IsValid := valid;
|
|
||||||
end;
|
|
||||||
|
|
||||||
columns.Add(c);
|
columns.Add(c);
|
||||||
RebuildSchema;
|
RebuildSchema;
|
||||||
|
|
@ -2245,21 +2238,10 @@ end;
|
||||||
|
|
||||||
procedure DataFrame.AddFloatColumn(name: string; data: array of real; valid: array of boolean);
|
procedure DataFrame.AddFloatColumn(name: string; data: array of real; valid: array of boolean);
|
||||||
begin
|
begin
|
||||||
if (columns.Count > 0) and (data.Length <> RowCount) then
|
if (columns.Count > 0) and (Length(data) <> RowCount) then
|
||||||
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
||||||
|
|
||||||
var c := new FloatColumn;
|
var c := new FloatColumn(name, data, valid);
|
||||||
c.Info := new ColumnInfo(name, ctFloat);
|
|
||||||
c.Data := data;
|
|
||||||
|
|
||||||
if valid = nil then
|
|
||||||
c.IsValid := [True] * data.Length
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if valid.Length <> data.Length then
|
|
||||||
DimensionError(ER_COLUMN_VALID_LENGTH_MISMATCH);
|
|
||||||
c.IsValid := valid;
|
|
||||||
end;
|
|
||||||
|
|
||||||
columns.Add(c);
|
columns.Add(c);
|
||||||
RebuildSchema;
|
RebuildSchema;
|
||||||
|
|
@ -2267,21 +2249,10 @@ end;
|
||||||
|
|
||||||
procedure DataFrame.AddStrColumn(name: string; data: array of string; valid: array of boolean);
|
procedure DataFrame.AddStrColumn(name: string; data: array of string; valid: array of boolean);
|
||||||
begin
|
begin
|
||||||
if (columns.Count > 0) and (data.Length <> RowCount) then
|
if (columns.Count > 0) and (Length(data) <> RowCount) then
|
||||||
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
||||||
|
|
||||||
var c := new StrColumn;
|
var c := new StrColumn(name, data, valid);
|
||||||
c.Info := new ColumnInfo(name, ctStr);
|
|
||||||
c.Data := data;
|
|
||||||
|
|
||||||
if valid = nil then
|
|
||||||
c.IsValid := [True] * data.Length
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if valid.Length <> data.Length then
|
|
||||||
DimensionError(ER_COLUMN_VALID_LENGTH_MISMATCH);
|
|
||||||
c.IsValid := valid;
|
|
||||||
end;
|
|
||||||
|
|
||||||
columns.Add(c);
|
columns.Add(c);
|
||||||
RebuildSchema;
|
RebuildSchema;
|
||||||
|
|
@ -2295,27 +2266,15 @@ end;
|
||||||
|
|
||||||
procedure DataFrame.AddBoolColumn(name: string; data: array of boolean; valid: array of boolean);
|
procedure DataFrame.AddBoolColumn(name: string; data: array of boolean; valid: array of boolean);
|
||||||
begin
|
begin
|
||||||
if (columns.Count > 0) and (data.Length <> RowCount) then
|
if (columns.Count > 0) and (Length(data) <> RowCount) then
|
||||||
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
DimensionError(ER_ADD_COLUMN_ROW_MISMATCH);
|
||||||
|
|
||||||
var c := new BoolColumn;
|
var c := new BoolColumn(name, data, valid);
|
||||||
c.Info := new ColumnInfo(name, ctBool);
|
|
||||||
c.Data := data;
|
|
||||||
|
|
||||||
if valid = nil then
|
|
||||||
c.IsValid := [True] * data.Length
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if valid.Length <> data.Length then
|
|
||||||
DimensionError(ER_COLUMN_VALID_LENGTH_MISMATCH);
|
|
||||||
c.IsValid := valid;
|
|
||||||
end;
|
|
||||||
|
|
||||||
columns.Add(c);
|
columns.Add(c);
|
||||||
RebuildSchema;
|
RebuildSchema;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure DataFrame.CheckColumnIndex(colIndex: integer);
|
procedure DataFrame.CheckColumnIndex(colIndex: integer);
|
||||||
begin
|
begin
|
||||||
if (colIndex < 0) or (colIndex >= ColumnCount) then
|
if (colIndex < 0) or (colIndex >= ColumnCount) then
|
||||||
|
|
@ -2917,17 +2876,13 @@ begin
|
||||||
var src := IntColumn(col);
|
var src := IntColumn(col);
|
||||||
|
|
||||||
var data := new integer[newCount];
|
var data := new integer[newCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[newCount];
|
||||||
|
|
||||||
if src.IsValid <> nil then
|
|
||||||
valid := new boolean[newCount];
|
|
||||||
|
|
||||||
for var k := 0 to newCount - 1 do
|
for var k := 0 to newCount - 1 do
|
||||||
begin
|
begin
|
||||||
var i := mask[k];
|
var i := mask[k];
|
||||||
data[k] := src.Data[i];
|
data[k] := src.Data[i];
|
||||||
if valid <> nil then
|
valid[k] := src.IsValid[i];
|
||||||
valid[k] := src.IsValid[i];
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddIntColumn(src.Info.Name, data, valid);
|
res.AddIntColumn(src.Info.Name, data, valid);
|
||||||
|
|
@ -2939,17 +2894,13 @@ begin
|
||||||
var src := FloatColumn(col);
|
var src := FloatColumn(col);
|
||||||
|
|
||||||
var data := new real[newCount];
|
var data := new real[newCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[newCount];
|
||||||
|
|
||||||
if src.IsValid <> nil then
|
|
||||||
valid := new boolean[newCount];
|
|
||||||
|
|
||||||
for var k := 0 to newCount - 1 do
|
for var k := 0 to newCount - 1 do
|
||||||
begin
|
begin
|
||||||
var i := mask[k];
|
var i := mask[k];
|
||||||
data[k] := src.Data[i];
|
data[k] := src.Data[i];
|
||||||
if valid <> nil then
|
valid[k] := src.IsValid[i];
|
||||||
valid[k] := src.IsValid[i];
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddFloatColumn(src.Info.Name, data, valid);
|
res.AddFloatColumn(src.Info.Name, data, valid);
|
||||||
|
|
@ -2961,17 +2912,13 @@ begin
|
||||||
var src := StrColumn(col);
|
var src := StrColumn(col);
|
||||||
|
|
||||||
var data := new string[newCount];
|
var data := new string[newCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[newCount];
|
||||||
|
|
||||||
if src.IsValid <> nil then
|
|
||||||
valid := new boolean[newCount];
|
|
||||||
|
|
||||||
for var k := 0 to newCount - 1 do
|
for var k := 0 to newCount - 1 do
|
||||||
begin
|
begin
|
||||||
var i := mask[k];
|
var i := mask[k];
|
||||||
data[k] := src.Data[i];
|
data[k] := src.Data[i];
|
||||||
if valid <> nil then
|
valid[k] := src.IsValid[i];
|
||||||
valid[k] := src.IsValid[i];
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddStrColumn(src.Info.Name, data, valid);
|
res.AddStrColumn(src.Info.Name, data, valid);
|
||||||
|
|
@ -2983,17 +2930,13 @@ begin
|
||||||
var src := BoolColumn(col);
|
var src := BoolColumn(col);
|
||||||
|
|
||||||
var data := new boolean[newCount];
|
var data := new boolean[newCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[newCount];
|
||||||
|
|
||||||
if src.IsValid <> nil then
|
|
||||||
valid := new boolean[newCount];
|
|
||||||
|
|
||||||
for var k := 0 to newCount - 1 do
|
for var k := 0 to newCount - 1 do
|
||||||
begin
|
begin
|
||||||
var i := mask[k];
|
var i := mask[k];
|
||||||
data[k] := src.Data[i];
|
data[k] := src.Data[i];
|
||||||
if valid <> nil then
|
valid[k] := src.IsValid[i];
|
||||||
valid[k] := src.IsValid[i];
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddBoolColumn(src.Info.Name, data, valid);
|
res.AddBoolColumn(src.Info.Name, data, valid);
|
||||||
|
|
@ -3251,16 +3194,6 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
static procedure DataFrame.EnsureValidArray(var valid: array of boolean; rowCount, filledCount: integer);
|
|
||||||
begin
|
|
||||||
if valid = nil then
|
|
||||||
begin
|
|
||||||
valid := new boolean[rowCount];
|
|
||||||
for var j := 0 to filledCount - 1 do
|
|
||||||
valid[j] := true;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function DataFrame.WithColumnInt(name: string; f: DataFrameCursor -> integer): DataFrame;
|
function DataFrame.WithColumnInt(name: string; f: DataFrameCursor -> integer): DataFrame;
|
||||||
begin
|
begin
|
||||||
if fSchema.HasColumn(name) then
|
if fSchema.HasColumn(name) then
|
||||||
|
|
@ -3269,7 +3202,7 @@ begin
|
||||||
var res := CloneWithCopiedColumns;
|
var res := CloneWithCopiedColumns;
|
||||||
|
|
||||||
var data := new integer[RowCount];
|
var data := new integer[RowCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[RowCount];
|
||||||
|
|
||||||
var cur := GetCursor;
|
var cur := GetCursor;
|
||||||
var i := 0;
|
var i := 0;
|
||||||
|
|
@ -3282,15 +3215,13 @@ begin
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
begin
|
begin
|
||||||
data[i] := 0;
|
data[i] := 0;
|
||||||
EnsureValidArray(valid, RowCount, i);
|
valid[i] := False;
|
||||||
valid[i] := false;
|
|
||||||
i += 1;
|
i += 1;
|
||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if valid <> nil then
|
valid[i] := True;
|
||||||
valid[i] := true;
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
end;
|
end;
|
||||||
|
|
@ -3310,7 +3241,7 @@ begin
|
||||||
var res := CloneWithCopiedColumns;
|
var res := CloneWithCopiedColumns;
|
||||||
|
|
||||||
var data := new real[RowCount];
|
var data := new real[RowCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[RowCount];
|
||||||
|
|
||||||
var cur := GetCursor;
|
var cur := GetCursor;
|
||||||
var i := 0;
|
var i := 0;
|
||||||
|
|
@ -3323,15 +3254,13 @@ begin
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
begin
|
begin
|
||||||
data[i] := 0.0;
|
data[i] := 0.0;
|
||||||
EnsureValidArray(valid, RowCount, i);
|
valid[i] := False;
|
||||||
valid[i] := false;
|
|
||||||
i += 1;
|
i += 1;
|
||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if valid <> nil then
|
valid[i] := True;
|
||||||
valid[i] := true;
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
end;
|
end;
|
||||||
|
|
@ -3351,7 +3280,7 @@ begin
|
||||||
var res := CloneWithCopiedColumns;
|
var res := CloneWithCopiedColumns;
|
||||||
|
|
||||||
var data := new string[RowCount];
|
var data := new string[RowCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[RowCount];
|
||||||
|
|
||||||
var cur := GetCursor;
|
var cur := GetCursor;
|
||||||
var i := 0;
|
var i := 0;
|
||||||
|
|
@ -3364,15 +3293,13 @@ begin
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
begin
|
begin
|
||||||
data[i] := nil;
|
data[i] := nil;
|
||||||
EnsureValidArray(valid, RowCount, i);
|
valid[i] := False;
|
||||||
valid[i] := false;
|
|
||||||
i += 1;
|
i += 1;
|
||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if valid <> nil then
|
valid[i] := True;
|
||||||
valid[i] := true;
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
end;
|
end;
|
||||||
|
|
@ -3392,7 +3319,7 @@ begin
|
||||||
var res := CloneWithCopiedColumns;
|
var res := CloneWithCopiedColumns;
|
||||||
|
|
||||||
var data := new boolean[RowCount];
|
var data := new boolean[RowCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[RowCount];
|
||||||
|
|
||||||
var cur := GetCursor;
|
var cur := GetCursor;
|
||||||
var i := 0;
|
var i := 0;
|
||||||
|
|
@ -3404,16 +3331,14 @@ begin
|
||||||
except
|
except
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
begin
|
begin
|
||||||
data[i] := false;
|
data[i] := False;
|
||||||
EnsureValidArray(valid, RowCount, i);
|
valid[i] := False;
|
||||||
valid[i] := false;
|
|
||||||
i += 1;
|
i += 1;
|
||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if valid <> nil then
|
valid[i] := True;
|
||||||
valid[i] := true;
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
end;
|
end;
|
||||||
|
|
@ -3458,7 +3383,7 @@ begin
|
||||||
var rowCount := RowCount;
|
var rowCount := RowCount;
|
||||||
|
|
||||||
var data := new real[rowCount];
|
var data := new real[rowCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[rowCount];
|
||||||
|
|
||||||
var cur := GetCursor;
|
var cur := GetCursor;
|
||||||
var row := 0;
|
var row := 0;
|
||||||
|
|
@ -3469,14 +3394,6 @@ begin
|
||||||
if not cur.IsValid(colIndex) then
|
if not cur.IsValid(colIndex) then
|
||||||
begin
|
begin
|
||||||
data[row] := 0.0;
|
data[row] := 0.0;
|
||||||
|
|
||||||
if valid = nil then
|
|
||||||
begin
|
|
||||||
valid := new boolean[rowCount];
|
|
||||||
for var j := 0 to row - 1 do
|
|
||||||
valid[j] := true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
valid[row] := false;
|
valid[row] := false;
|
||||||
row += 1;
|
row += 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -3489,22 +3406,13 @@ begin
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
begin
|
begin
|
||||||
data[row] := 0.0;
|
data[row] := 0.0;
|
||||||
|
valid[row] := False;
|
||||||
if valid = nil then
|
|
||||||
begin
|
|
||||||
valid := new boolean[rowCount];
|
|
||||||
for var j := 0 to row - 1 do
|
|
||||||
valid[j] := true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
valid[row] := false;
|
|
||||||
row += 1;
|
row += 1;
|
||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if valid <> nil then
|
valid[row] := True;
|
||||||
valid[row] := true;
|
|
||||||
|
|
||||||
row += 1;
|
row += 1;
|
||||||
end;
|
end;
|
||||||
|
|
@ -3540,7 +3448,7 @@ begin
|
||||||
var rowCount := RowCount;
|
var rowCount := RowCount;
|
||||||
|
|
||||||
var data := new integer[rowCount];
|
var data := new integer[rowCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[rowCount];
|
||||||
|
|
||||||
var cur := GetCursor;
|
var cur := GetCursor;
|
||||||
var row := 0;
|
var row := 0;
|
||||||
|
|
@ -3548,17 +3456,12 @@ begin
|
||||||
begin
|
begin
|
||||||
try
|
try
|
||||||
data[row] := f(cur);
|
data[row] := f(cur);
|
||||||
if valid <> nil then valid[row] := true;
|
valid[row] := True;
|
||||||
except
|
except
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
begin
|
begin
|
||||||
data[row] := 0;
|
data[row] := 0;
|
||||||
if valid = nil then
|
valid[row] := False;
|
||||||
begin
|
|
||||||
valid := new boolean[rowCount];
|
|
||||||
for var j := 0 to row - 1 do valid[j] := true;
|
|
||||||
end;
|
|
||||||
valid[row] := false;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
row += 1;
|
row += 1;
|
||||||
|
|
@ -3597,7 +3500,7 @@ begin
|
||||||
|
|
||||||
var rowCount := RowCount;
|
var rowCount := RowCount;
|
||||||
var data := new integer[rowCount];
|
var data := new integer[rowCount];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[rowCount];
|
||||||
|
|
||||||
var cur := GetCursor;
|
var cur := GetCursor;
|
||||||
var row := 0;
|
var row := 0;
|
||||||
|
|
@ -3605,17 +3508,12 @@ begin
|
||||||
begin
|
begin
|
||||||
try
|
try
|
||||||
data[row] := f(cur);
|
data[row] := f(cur);
|
||||||
if valid <> nil then valid[row] := true;
|
valid[row] := True;
|
||||||
except
|
except
|
||||||
on e: Exception do
|
on e: Exception do
|
||||||
begin
|
begin
|
||||||
data[row] := 0;
|
data[row] := 0;
|
||||||
if valid = nil then
|
valid[row] := False;
|
||||||
begin
|
|
||||||
valid := new boolean[rowCount];
|
|
||||||
for var j := 0 to row - 1 do valid[j] := true;
|
|
||||||
end;
|
|
||||||
valid[row] := false;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
row += 1;
|
row += 1;
|
||||||
|
|
@ -3863,11 +3761,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var src := IntColumn(col);
|
var src := IntColumn(col);
|
||||||
var data := new integer[k];
|
var data := new integer[k];
|
||||||
var validSrc := src.IsValid;
|
var validDst := new boolean[k];
|
||||||
var validDst: array of boolean := nil;
|
|
||||||
|
|
||||||
if validSrc <> nil then
|
|
||||||
validDst := new boolean[k];
|
|
||||||
|
|
||||||
for var j := 0 to k - 1 do
|
for var j := 0 to k - 1 do
|
||||||
begin
|
begin
|
||||||
|
|
@ -3876,15 +3770,8 @@ begin
|
||||||
if (i < 0) or (i >= RowCount) then
|
if (i < 0) or (i >= RowCount) then
|
||||||
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
||||||
|
|
||||||
if validSrc = nil then
|
data[j] := src.Data[i];
|
||||||
data[j] := src.Data[i]
|
validDst[j] := src.IsValid[i];
|
||||||
else if validSrc[i] then
|
|
||||||
begin
|
|
||||||
data[j] := src.Data[i];
|
|
||||||
validDst[j] := true;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
validDst[j] := false;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddIntColumn(name, data, validDst);
|
res.AddIntColumn(name, data, validDst);
|
||||||
|
|
@ -3894,11 +3781,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var src := FloatColumn(col);
|
var src := FloatColumn(col);
|
||||||
var data := new real[k];
|
var data := new real[k];
|
||||||
var validSrc := src.IsValid;
|
var validDst := new boolean[k];
|
||||||
var validDst: array of boolean := nil;
|
|
||||||
|
|
||||||
if validSrc <> nil then
|
|
||||||
validDst := new boolean[k];
|
|
||||||
|
|
||||||
for var j := 0 to k - 1 do
|
for var j := 0 to k - 1 do
|
||||||
begin
|
begin
|
||||||
|
|
@ -3907,15 +3790,8 @@ begin
|
||||||
if (i < 0) or (i >= RowCount) then
|
if (i < 0) or (i >= RowCount) then
|
||||||
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
||||||
|
|
||||||
if validSrc = nil then
|
data[j] := src.Data[i];
|
||||||
data[j] := src.Data[i]
|
validDst[j] := src.IsValid[i];
|
||||||
else if validSrc[i] then
|
|
||||||
begin
|
|
||||||
data[j] := src.Data[i];
|
|
||||||
validDst[j] := true;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
validDst[j] := false;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddFloatColumn(name, data, validDst);
|
res.AddFloatColumn(name, data, validDst);
|
||||||
|
|
@ -3925,11 +3801,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var src := StrColumn(col);
|
var src := StrColumn(col);
|
||||||
var data := new string[k];
|
var data := new string[k];
|
||||||
var validSrc := src.IsValid;
|
var validDst := new boolean[k];
|
||||||
var validDst: array of boolean := nil;
|
|
||||||
|
|
||||||
if validSrc <> nil then
|
|
||||||
validDst := new boolean[k];
|
|
||||||
|
|
||||||
for var j := 0 to k - 1 do
|
for var j := 0 to k - 1 do
|
||||||
begin
|
begin
|
||||||
|
|
@ -3938,15 +3810,8 @@ begin
|
||||||
if (i < 0) or (i >= RowCount) then
|
if (i < 0) or (i >= RowCount) then
|
||||||
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
||||||
|
|
||||||
if validSrc = nil then
|
data[j] := src.Data[i];
|
||||||
data[j] := src.Data[i]
|
validDst[j] := src.IsValid[i];
|
||||||
else if validSrc[i] then
|
|
||||||
begin
|
|
||||||
data[j] := src.Data[i];
|
|
||||||
validDst[j] := true;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
validDst[j] := false;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddStrColumn(name, data, validDst);
|
res.AddStrColumn(name, data, validDst);
|
||||||
|
|
@ -3956,11 +3821,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var src := BoolColumn(col);
|
var src := BoolColumn(col);
|
||||||
var data := new boolean[k];
|
var data := new boolean[k];
|
||||||
var validSrc := src.IsValid;
|
var validDst := new boolean[k];
|
||||||
var validDst: array of boolean := nil;
|
|
||||||
|
|
||||||
if validSrc <> nil then
|
|
||||||
validDst := new boolean[k];
|
|
||||||
|
|
||||||
for var j := 0 to k - 1 do
|
for var j := 0 to k - 1 do
|
||||||
begin
|
begin
|
||||||
|
|
@ -3969,15 +3830,8 @@ begin
|
||||||
if (i < 0) or (i >= RowCount) then
|
if (i < 0) or (i >= RowCount) then
|
||||||
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
ArgumentError(ER_ROW_INDEX_OUT_OF_RANGE, i);
|
||||||
|
|
||||||
if validSrc = nil then
|
data[j] := src.Data[i];
|
||||||
data[j] := src.Data[i]
|
validDst[j] := src.IsValid[i];
|
||||||
else if validSrc[i] then
|
|
||||||
begin
|
|
||||||
data[j] := src.Data[i];
|
|
||||||
validDst[j] := true;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
validDst[j] := false;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
res.AddBoolColumn(name, data, validDst);
|
res.AddBoolColumn(name, data, validDst);
|
||||||
|
|
@ -4305,13 +4159,10 @@ begin
|
||||||
case src.Info.ColType of
|
case src.Info.ColType of
|
||||||
ctInt:
|
ctInt:
|
||||||
AddIntColumn(src.Info.Name, IntColumn(src).Data, IntColumn(src).IsValid);
|
AddIntColumn(src.Info.Name, IntColumn(src).Data, IntColumn(src).IsValid);
|
||||||
|
|
||||||
ctFloat:
|
ctFloat:
|
||||||
AddFloatColumn(src.Info.Name, FloatColumn(src).Data, FloatColumn(src).IsValid);
|
AddFloatColumn(src.Info.Name, FloatColumn(src).Data, FloatColumn(src).IsValid);
|
||||||
|
|
||||||
ctStr:
|
ctStr:
|
||||||
AddStrColumn(src.Info.Name, StrColumn(src).Data, StrColumn(src).IsValid);
|
AddStrColumn(src.Info.Name, StrColumn(src).Data, StrColumn(src).IsValid);
|
||||||
|
|
||||||
ctBool:
|
ctBool:
|
||||||
AddBoolColumn(src.Info.Name, BoolColumn(src).Data, BoolColumn(src).IsValid);
|
AddBoolColumn(src.Info.Name, BoolColumn(src).Data, BoolColumn(src).IsValid);
|
||||||
end;
|
end;
|
||||||
|
|
@ -4559,7 +4410,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var i := indices[j];
|
var i := indices[j];
|
||||||
|
|
||||||
if (valid <> nil) and not valid[i] then
|
if not valid[i] then
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
s += if isInt then dataInt[i] else dataFloat[i];
|
s += if isInt then dataInt[i] else dataFloat[i];
|
||||||
|
|
@ -4586,7 +4437,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var i := indices[j];
|
var i := indices[j];
|
||||||
|
|
||||||
if (valid <> nil) and not valid[i] then
|
if not valid[i] then
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
s += if isInt then dataInt[i] else dataFloat[i];
|
s += if isInt then dataInt[i] else dataFloat[i];
|
||||||
|
|
@ -4614,7 +4465,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var i := indices[j];
|
var i := indices[j];
|
||||||
|
|
||||||
if (valid <> nil) and not valid[i] then
|
if not valid[i] then
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var v := if isInt then dataInt[i] else dataFloat[i];
|
var v := if isInt then dataInt[i] else dataFloat[i];
|
||||||
|
|
@ -4647,7 +4498,7 @@ begin
|
||||||
begin
|
begin
|
||||||
var i := indices[j];
|
var i := indices[j];
|
||||||
|
|
||||||
if (valid <> nil) and not valid[i] then
|
if not valid[i] then
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var v := if isInt then dataInt[i] else dataFloat[i];
|
var v := if isInt then dataInt[i] else dataFloat[i];
|
||||||
|
|
@ -5578,7 +5429,7 @@ begin
|
||||||
if cur.IsValid(i) then
|
if cur.IsValid(i) then
|
||||||
col.Data[row] := (cur.Float(i) - means[i]) / stds[i]
|
col.Data[row] := (cur.Float(i) - means[i]) / stds[i]
|
||||||
else
|
else
|
||||||
col.IsValid[row] := false;
|
col.IsValid[row] := False;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
row += 1;
|
row += 1;
|
||||||
|
|
@ -5661,20 +5512,11 @@ begin
|
||||||
if cur.IsValid(i) then
|
if cur.IsValid(i) then
|
||||||
begin
|
begin
|
||||||
col.Data[row] := (cur.Float(i) - mins[i]) / (maxs[i] - mins[i]);
|
col.Data[row] := (cur.Float(i) - mins[i]) / (maxs[i] - mins[i]);
|
||||||
if col.IsValid <> nil then
|
col.IsValid[row] := True;
|
||||||
col.IsValid[row] := true;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
|
||||||
// первый NA → создаём IsValid
|
// первый NA → создаём IsValid
|
||||||
if col.IsValid = nil then
|
col.IsValid[row] := False;
|
||||||
begin
|
|
||||||
col.IsValid := new boolean[df.RowCount];
|
|
||||||
for var r := 0 to row - 1 do
|
|
||||||
col.IsValid[r] := true;
|
|
||||||
end;
|
|
||||||
col.IsValid[row] := false;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
row += 1;
|
row += 1;
|
||||||
end;
|
end;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,20 @@
|
||||||
unit DataFrameABCCore;
|
unit DataFrameABCCore;
|
||||||
|
|
||||||
|
// =============================================================
|
||||||
|
// ИНВАРИАНТ ВАЛИДНОСТИ СТОЛБЦОВ
|
||||||
|
//
|
||||||
|
// Для всех столбцов:
|
||||||
|
// • IsValid всегда инициализирован
|
||||||
|
// • Length(IsValid) = Length(Data)
|
||||||
|
// • nil не используется как специальное значение
|
||||||
|
//
|
||||||
|
// Пустой столбец:
|
||||||
|
// • Data имеет длину 0
|
||||||
|
// • IsValid = new boolean[0]
|
||||||
|
//
|
||||||
|
// Нарушение этого инварианта считается ошибкой.
|
||||||
|
// =============================================================
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -276,6 +291,8 @@ const
|
||||||
ER_ROW_INDEX_OUT_OF_RANGE =
|
ER_ROW_INDEX_OUT_OF_RANGE =
|
||||||
'Индекс строки {0} вне диапазона [0..{1})!!' +
|
'Индекс строки {0} вне диапазона [0..{1})!!' +
|
||||||
'Row index {0} out of range [0..{1})';
|
'Row index {0} out of range [0..{1})';
|
||||||
|
ER_INVALID_ISVALID_LENGTH =
|
||||||
|
'Длина IsValid должна совпадать с длиной Data!!IsValid length must match Data length';
|
||||||
|
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
// Сервисные функции
|
// Сервисные функции
|
||||||
|
|
@ -547,14 +564,23 @@ end;
|
||||||
// Columns
|
// Columns
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
|
|
||||||
constructor IntColumn.Create(name: string; data: array of integer;
|
constructor IntColumn.Create(name: string; data: array of integer; valid: array of boolean);
|
||||||
valid: array of boolean);
|
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctInt);
|
Info := new ColumnInfo(name, ctInt);
|
||||||
|
|
||||||
Data := data;
|
var n := Length(data);
|
||||||
IsValid := valid;
|
Data := if n = 0 then [] else data;
|
||||||
|
|
||||||
|
if valid = nil then
|
||||||
|
IsValid := [True] * n
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if Length(valid) <> n then
|
||||||
|
Error(ER_INVALID_ISVALID_LENGTH);
|
||||||
|
|
||||||
|
IsValid := valid;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor IntColumn.Create(name: string);
|
constructor IntColumn.Create(name: string);
|
||||||
|
|
@ -562,55 +588,73 @@ begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctInt);
|
Info := new ColumnInfo(name, ctInt);
|
||||||
|
|
||||||
Data := new integer[0];
|
Data := [];
|
||||||
IsValid := nil;
|
IsValid := [];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IntColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
function IntColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
||||||
begin
|
begin
|
||||||
if (IsValid <> nil) and not IsValid[i] then
|
if not IsValid[i] then
|
||||||
exit(false);
|
exit(False);
|
||||||
|
|
||||||
value := Data[i];
|
value := Data[i];
|
||||||
exit(true);
|
exit(True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor FloatColumn.Create(name: string; data: array of real;
|
constructor FloatColumn.Create(name: string; data: array of real; valid: array of boolean);
|
||||||
valid: array of boolean);
|
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctFloat);
|
Info := new ColumnInfo(name, ctFloat);
|
||||||
|
|
||||||
Data := data;
|
var n := Length(data);
|
||||||
IsValid := valid;
|
Data := if n = 0 then [] else data;
|
||||||
|
|
||||||
|
if valid = nil then
|
||||||
|
IsValid := [True] * n
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if Length(valid) <> n then
|
||||||
|
Error(ER_INVALID_ISVALID_LENGTH);
|
||||||
|
|
||||||
|
IsValid := valid;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor FloatColumn.Create(name: string);
|
constructor FloatColumn.Create(name: string);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctFloat);
|
Info := new ColumnInfo(name, ctFloat);
|
||||||
Data := new real[0];
|
|
||||||
IsValid := nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
Data := [];
|
||||||
|
IsValid := [];
|
||||||
|
end;
|
||||||
|
|
||||||
function FloatColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
function FloatColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
||||||
begin
|
begin
|
||||||
if (IsValid <> nil) and not IsValid[i] then
|
if not IsValid[i] then
|
||||||
exit(false);
|
exit(False);
|
||||||
|
|
||||||
value := Data[i];
|
value := Data[i];
|
||||||
exit(true);
|
exit(True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor StrColumn.Create(name: string; data: array of string;
|
constructor StrColumn.Create(name: string; data: array of string; valid: array of boolean);
|
||||||
valid: array of boolean);
|
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctStr);
|
Info := new ColumnInfo(name, ctStr);
|
||||||
|
|
||||||
Data := data;
|
var n := Length(data);
|
||||||
IsValid := valid;
|
Data := if n = 0 then [] else data;
|
||||||
|
|
||||||
|
if valid = nil then
|
||||||
|
IsValid := [True] * n
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if Length(valid) <> n then
|
||||||
|
Error(ER_INVALID_ISVALID_LENGTH);
|
||||||
|
|
||||||
|
IsValid := valid;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor StrColumn.Create(name: string);
|
constructor StrColumn.Create(name: string);
|
||||||
|
|
@ -618,36 +662,32 @@ begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctStr);
|
Info := new ColumnInfo(name, ctStr);
|
||||||
|
|
||||||
Data := new string[0];
|
Data := [];
|
||||||
IsValid := nil;
|
IsValid := [];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function StrColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
function StrColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
||||||
begin
|
begin
|
||||||
exit(false);
|
exit(False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function BoolColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
constructor BoolColumn.Create(name: string; data: array of boolean; valid: array of boolean);
|
||||||
begin
|
|
||||||
if (IsValid <> nil) and not IsValid[i] then
|
|
||||||
exit(false);
|
|
||||||
|
|
||||||
if Data[i] then
|
|
||||||
value := 1.0
|
|
||||||
else
|
|
||||||
value := 0.0;
|
|
||||||
|
|
||||||
exit(true);
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor BoolColumn.Create(name: string; data: array of boolean;
|
|
||||||
valid: array of boolean);
|
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctBool);
|
Info := new ColumnInfo(name, ctBool);
|
||||||
|
|
||||||
Data := data;
|
var n := Length(data);
|
||||||
IsValid := valid;
|
Data := if n = 0 then [] else data;
|
||||||
|
|
||||||
|
if valid = nil then
|
||||||
|
IsValid := [True] * n
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if Length(valid) <> n then
|
||||||
|
Error(ER_INVALID_ISVALID_LENGTH);
|
||||||
|
|
||||||
|
IsValid := valid;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor BoolColumn.Create(name: string);
|
constructor BoolColumn.Create(name: string);
|
||||||
|
|
@ -655,34 +695,24 @@ begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Info := new ColumnInfo(name, ctBool);
|
Info := new ColumnInfo(name, ctBool);
|
||||||
|
|
||||||
Data := new boolean[0];
|
Data := [];
|
||||||
IsValid := nil;
|
IsValid := [];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{procedure BoolColumn.AppendFromCursor(cur: DataFrameCursor; colIndex: integer);
|
function BoolColumn.TryGetNumericValue(i: integer; var value: real): boolean;
|
||||||
begin
|
begin
|
||||||
if cur.IsValid(colIndex) then
|
if not IsValid[i] then
|
||||||
begin
|
exit(False);
|
||||||
Data := Data + [cur.Bool(colIndex)];
|
|
||||||
if IsValid <> nil then
|
|
||||||
IsValid := IsValid + [true];
|
|
||||||
end
|
|
||||||
else AppendInvalid;
|
|
||||||
end;}
|
|
||||||
|
|
||||||
{procedure BoolColumn.AppendInvalid;
|
if Data[i] then
|
||||||
begin
|
value := 1.0
|
||||||
Data := Data + [false];
|
else
|
||||||
|
value := 0.0;
|
||||||
|
|
||||||
|
exit(True);
|
||||||
|
end;
|
||||||
|
|
||||||
if IsValid = nil then
|
|
||||||
begin
|
|
||||||
IsValid := new boolean[Length(Data) - 1];
|
|
||||||
for var i := 0 to IsValid.Length - 1 do
|
|
||||||
IsValid[i] := true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
IsValid := IsValid + [false];
|
|
||||||
end;}
|
|
||||||
|
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
// JoinKey
|
// JoinKey
|
||||||
|
|
@ -772,10 +802,7 @@ begin
|
||||||
ctInt:
|
ctInt:
|
||||||
begin
|
begin
|
||||||
var c := IntColumn(col);
|
var c := IntColumn(col);
|
||||||
if c.IsValid = nil then
|
validAcc[i] := pos -> c.IsValid[pos];
|
||||||
validAcc[i] := pos -> true
|
|
||||||
else
|
|
||||||
validAcc[i] := pos -> c.IsValid[pos];
|
|
||||||
|
|
||||||
intAcc[i] := pos -> c.Data[pos];
|
intAcc[i] := pos -> c.Data[pos];
|
||||||
floatAcc[i] := pos -> c.Data[pos];
|
floatAcc[i] := pos -> c.Data[pos];
|
||||||
|
|
@ -784,10 +811,7 @@ begin
|
||||||
ctFloat:
|
ctFloat:
|
||||||
begin
|
begin
|
||||||
var c := FloatColumn(col);
|
var c := FloatColumn(col);
|
||||||
if c.IsValid = nil then
|
validAcc[i] := pos -> c.IsValid[pos];
|
||||||
validAcc[i] := pos -> true
|
|
||||||
else
|
|
||||||
validAcc[i] := pos -> c.IsValid[pos];
|
|
||||||
|
|
||||||
floatAcc[i] := pos -> c.Data[pos];
|
floatAcc[i] := pos -> c.Data[pos];
|
||||||
intAcc[i] := NotInt;
|
intAcc[i] := NotInt;
|
||||||
|
|
@ -796,10 +820,7 @@ begin
|
||||||
ctStr:
|
ctStr:
|
||||||
begin
|
begin
|
||||||
var c := StrColumn(col);
|
var c := StrColumn(col);
|
||||||
if c.IsValid = nil then
|
validAcc[i] := pos -> c.IsValid[pos];
|
||||||
validAcc[i] := pos -> true
|
|
||||||
else
|
|
||||||
validAcc[i] := pos -> c.IsValid[pos];
|
|
||||||
|
|
||||||
strAcc[i] := pos -> c.Data[pos];
|
strAcc[i] := pos -> c.Data[pos];
|
||||||
end;
|
end;
|
||||||
|
|
@ -807,10 +828,7 @@ begin
|
||||||
ctBool:
|
ctBool:
|
||||||
begin
|
begin
|
||||||
var c := BoolColumn(col);
|
var c := BoolColumn(col);
|
||||||
if c.IsValid = nil then
|
validAcc[i] := pos -> c.IsValid[pos];
|
||||||
validAcc[i] := pos -> true
|
|
||||||
else
|
|
||||||
validAcc[i] := pos -> c.IsValid[pos];
|
|
||||||
|
|
||||||
boolAcc[i] := pos -> c.Data[pos];
|
boolAcc[i] := pos -> c.Data[pos];
|
||||||
end;
|
end;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,13 @@
|
||||||
/// Линейная алгебра для алгоритмов машинного обучения.
|
// =============================================================
|
||||||
|
// СТАТИСТИЧЕСКОЕ СОГЛАШЕНИЕ (LinearAlgebraML)
|
||||||
|
//
|
||||||
|
// Используется дисперсия генеральной совокупности (деление на n),
|
||||||
|
// как принято в численных методах и алгоритмах машинного обучения.
|
||||||
|
//
|
||||||
|
// См. статистическую политику в модуле MLABC.
|
||||||
|
// =============================================================
|
||||||
|
|
||||||
|
/// Линейная алгебра для алгоритмов машинного обучения.
|
||||||
///
|
///
|
||||||
/// Содержит типы Vector и Matrix и численные методы,
|
/// Содержит типы Vector и Matrix и численные методы,
|
||||||
/// используемые в моделях ML:
|
/// используемые в моделях ML:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,23 @@
|
||||||
/// Основной модуль библиотеки машинного обучения.
|
// =============================================================
|
||||||
|
// СТАТИСТИЧЕСКАЯ ПОЛИТИКА БИБЛИОТЕКИ ML PascalABC.NET
|
||||||
|
//
|
||||||
|
// В библиотеке используются следующие соглашения:
|
||||||
|
//
|
||||||
|
// 1. DataFrame (описательная статистика):
|
||||||
|
// • дисперсия вычисляется с делением на (n - 1)
|
||||||
|
//
|
||||||
|
// 2. LinearAlgebra и ML:
|
||||||
|
// • дисперсия вычисляется с делением на n
|
||||||
|
//
|
||||||
|
// 3. PCA:
|
||||||
|
// • ковариационная матрица вычисляется с делением на (n - 1)
|
||||||
|
//
|
||||||
|
// Это соответствует распространённой практике:
|
||||||
|
// • описательная статистика — выборочная дисперсия
|
||||||
|
// • алгоритмы ML — дисперсия генеральной совокупности
|
||||||
|
// =============================================================
|
||||||
|
|
||||||
|
/// Основной модуль библиотеки машинного обучения.
|
||||||
/// Объединяет модели, метрики, валидацию и вспомогательные компоненты.
|
/// Объединяет модели, метрики, валидацию и вспомогательные компоненты.
|
||||||
unit MLABC;
|
unit MLABC;
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -8,6 +8,24 @@ interface
|
||||||
|
|
||||||
uses LinearAlgebraML;
|
uses LinearAlgebraML;
|
||||||
|
|
||||||
|
/// Определяет фактический seed для генератора случайных чисел.
|
||||||
|
///
|
||||||
|
/// Если seed >= 0:
|
||||||
|
/// • используется заданное пользователем значение
|
||||||
|
/// • userProvided := true
|
||||||
|
///
|
||||||
|
/// Если seed < 0:
|
||||||
|
/// • генерируется псевдослучайный seed на основе системного времени
|
||||||
|
/// • userProvided := false
|
||||||
|
///
|
||||||
|
/// Возвращает:
|
||||||
|
/// • неотрицательный seed, используемый для инициализации RNG
|
||||||
|
///
|
||||||
|
/// Назначение:
|
||||||
|
/// • обеспечить единое поведение случайности во всех моделях
|
||||||
|
/// • сохранить воспроизводимость при явном задании seed
|
||||||
|
function ResolveRandomSeed(seed: integer; var userProvided: boolean): integer;
|
||||||
|
|
||||||
/// Преобразует вектор меток классов в массив целых чисел.
|
/// Преобразует вектор меток классов в массив целых чисел.
|
||||||
/// Используется при визуализации и других задачах,
|
/// Используется при визуализации и других задачах,
|
||||||
/// где метки должны быть представлены как 0,1,2,...
|
/// где метки должны быть представлены как 0,1,2,...
|
||||||
|
|
@ -70,6 +88,20 @@ const
|
||||||
'Индекс метки {0} вне диапазона [0, {1})!!Label index {0} is out of range [0, {1})';
|
'Индекс метки {0} вне диапазона [0, {1})!!Label index {0} is out of range [0, {1})';
|
||||||
|
|
||||||
|
|
||||||
|
function ResolveRandomSeed(seed: integer; var userProvided: boolean): integer;
|
||||||
|
begin
|
||||||
|
if seed < 0 then
|
||||||
|
begin
|
||||||
|
userProvided := false;
|
||||||
|
Result := System.Environment.TickCount and integer.MaxValue;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
userProvided := true;
|
||||||
|
Result := seed;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function LabelsToInts(y: Vector): array of integer;
|
function LabelsToInts(y: Vector): array of integer;
|
||||||
begin
|
begin
|
||||||
if y = nil then
|
if y = nil then
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,18 @@ type
|
||||||
/// Создаёт LabelEncoder для указанного столбца
|
/// Создаёт LabelEncoder для указанного столбца
|
||||||
constructor Create(column: string);
|
constructor Create(column: string);
|
||||||
|
|
||||||
/// Определяет множество категорий и сохраняет их коды
|
/// Определяет множество категорий столбца и сохраняет их числовое кодирование.
|
||||||
|
/// df — таблица данных.
|
||||||
|
/// Сохраняет отображение категорий в числовые коды для последующего применения.
|
||||||
|
///
|
||||||
|
/// Примечание:
|
||||||
|
/// • отображение категорий НЕ копируется методом Clone
|
||||||
function Fit(df: DataFrame): IPreprocessor;
|
function Fit(df: DataFrame): IPreprocessor;
|
||||||
|
|
||||||
/// Заменяет категории их числовыми кодами
|
/// Заменяет категории их числовыми кодами
|
||||||
/// Возвращает новый DataFrame
|
/// Возвращает новый DataFrame
|
||||||
function Transform(df: DataFrame): DataFrame;
|
function Transform(df: DataFrame): DataFrame;
|
||||||
|
|
||||||
/// Выполняет Fit и Transform последовательно
|
/// Выполняет Fit и Transform последовательно
|
||||||
function FitTransform(df: DataFrame): DataFrame;
|
function FitTransform(df: DataFrame): DataFrame;
|
||||||
|
|
||||||
|
|
@ -65,6 +72,15 @@ type
|
||||||
|
|
||||||
property ColumnName: string read col;
|
property ColumnName: string read col;
|
||||||
|
|
||||||
|
/// Создаёт копию препроцессора с той же конфигурацией.
|
||||||
|
///
|
||||||
|
/// ВАЖНО:
|
||||||
|
/// • Clone копирует только конфигурацию (например, имя столбца)
|
||||||
|
/// • Clone НЕ копирует обученное состояние (mapping, статистики и т.п.)
|
||||||
|
///
|
||||||
|
/// Назначение:
|
||||||
|
/// • использование в Pipeline и CrossValidate
|
||||||
|
/// • обеспечивает независимое переобучение препроцессоров
|
||||||
function Clone: IPreprocessor;
|
function Clone: IPreprocessor;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -82,8 +98,14 @@ type
|
||||||
/// Создаёт OneHotEncoder для указанного столбца
|
/// Создаёт OneHotEncoder для указанного столбца
|
||||||
constructor Create(column: string);
|
constructor Create(column: string);
|
||||||
|
|
||||||
/// Определяет множество категорий столбца
|
/// Определяет множество категорий столбца.
|
||||||
|
/// df — таблица данных.
|
||||||
|
/// Сохраняет категории для последующего преобразования в one-hot представление.
|
||||||
|
///
|
||||||
|
/// Примечание:
|
||||||
|
/// • категории НЕ копируются методом Clone
|
||||||
function Fit(df: DataFrame): IPreprocessor;
|
function Fit(df: DataFrame): IPreprocessor;
|
||||||
|
|
||||||
/// Заменяет столбец набором бинарных столбцов
|
/// Заменяет столбец набором бинарных столбцов
|
||||||
/// Возвращает новый DataFrame
|
/// Возвращает новый DataFrame
|
||||||
function Transform(df: DataFrame): DataFrame;
|
function Transform(df: DataFrame): DataFrame;
|
||||||
|
|
@ -94,6 +116,15 @@ type
|
||||||
|
|
||||||
property ColumnName: string read col;
|
property ColumnName: string read col;
|
||||||
|
|
||||||
|
/// Создаёт копию препроцессора с той же конфигурацией.
|
||||||
|
///
|
||||||
|
/// ВАЖНО:
|
||||||
|
/// • Clone копирует только конфигурацию (например, имя столбца)
|
||||||
|
/// • Clone НЕ копирует обученное состояние (mapping, статистики и т.п.)
|
||||||
|
///
|
||||||
|
/// Назначение:
|
||||||
|
/// • использование в Pipeline и CrossValidate
|
||||||
|
/// • обеспечивает независимое переобучение препроцессоров
|
||||||
function Clone: IPreprocessor;
|
function Clone: IPreprocessor;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -118,11 +149,19 @@ type
|
||||||
/// Создаёт Imputer с константной стратегией заполнения
|
/// Создаёт Imputer с константной стратегией заполнения
|
||||||
constructor Create(value: object; params columns: array of string);
|
constructor Create(value: object; params columns: array of string);
|
||||||
|
|
||||||
/// Вычисляет значения для заполнения пропусков
|
/// Вычисляет значения для заполнения пропусков.
|
||||||
|
/// df — таблица данных.
|
||||||
|
/// В зависимости от стратегии вычисляет параметры заполнения
|
||||||
|
/// (например, среднее, медиану или константу) для каждого столбца.
|
||||||
|
///
|
||||||
|
/// Примечание:
|
||||||
|
/// • вычисленные параметры НЕ копируются методом Clone
|
||||||
function Fit(df: DataFrame): IPreprocessor;
|
function Fit(df: DataFrame): IPreprocessor;
|
||||||
|
|
||||||
/// Заполняет пропущенные значения в DataFrame
|
/// Заполняет пропущенные значения в DataFrame
|
||||||
/// Возвращает новый DataFrame
|
/// Возвращает новый DataFrame
|
||||||
function Transform(df: DataFrame): DataFrame;
|
function Transform(df: DataFrame): DataFrame;
|
||||||
|
|
||||||
/// Выполняет Fit и Transform последовательно
|
/// Выполняет Fit и Transform последовательно
|
||||||
function FitTransform(df: DataFrame): DataFrame;
|
function FitTransform(df: DataFrame): DataFrame;
|
||||||
|
|
||||||
|
|
@ -130,6 +169,15 @@ type
|
||||||
|
|
||||||
property Columns: array of string read cols;
|
property Columns: array of string read cols;
|
||||||
|
|
||||||
|
/// Создаёт копию препроцессора с той же конфигурацией.
|
||||||
|
///
|
||||||
|
/// ВАЖНО:
|
||||||
|
/// • Clone копирует только конфигурацию (например, имя столбца)
|
||||||
|
/// • Clone НЕ копирует обученное состояние (mapping, статистики и т.п.)
|
||||||
|
///
|
||||||
|
/// Назначение:
|
||||||
|
/// • использование в Pipeline и CrossValidate
|
||||||
|
/// • обеспечивает независимое переобучение препроцессоров
|
||||||
function Clone: IPreprocessor;
|
function Clone: IPreprocessor;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -262,7 +310,7 @@ begin
|
||||||
var n := df.RowCount;
|
var n := df.RowCount;
|
||||||
|
|
||||||
var data := new integer[n];
|
var data := new integer[n];
|
||||||
var valid: array of boolean := nil;
|
var valid := new boolean[n];
|
||||||
|
|
||||||
var cur := df.GetCursor;
|
var cur := df.GetCursor;
|
||||||
var row := 0;
|
var row := 0;
|
||||||
|
|
@ -270,13 +318,7 @@ begin
|
||||||
begin
|
begin
|
||||||
if not cur.IsValid(idx) then
|
if not cur.IsValid(idx) then
|
||||||
begin
|
begin
|
||||||
if valid = nil then
|
valid[row] := False;
|
||||||
begin
|
|
||||||
valid := new boolean[n];
|
|
||||||
for var j := 0 to row - 1 do
|
|
||||||
valid[j] := true;
|
|
||||||
end;
|
|
||||||
valid[row] := false;
|
|
||||||
data[row] := 0;
|
data[row] := 0;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
@ -287,8 +329,7 @@ begin
|
||||||
Error(ER_LABELENCODER_UNSEEN_CATEGORY, s);
|
Error(ER_LABELENCODER_UNSEEN_CATEGORY, s);
|
||||||
|
|
||||||
data[row] := mapping[s];
|
data[row] := mapping[s];
|
||||||
if valid <> nil then
|
valid[row] := True;
|
||||||
valid[row] := true;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
row += 1;
|
row += 1;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue