public double GetMultiColumnEntropy(DataTable table, params Column[] columns) { try { IEscaper escaper = table.Database.Escaper; //Select statement is actually just "SELECT SUM(pcount * log10({2} / pcount)) / (log10(2) * {2}) " //Obfuscated due to postgresql different log function names. //The .0 after the first {2} is to force float type string sourceQuery = @"SELECT " + escaper.RoundFunction("SUM(pcount * " + escaper.Log10Function("{2}.0 / pcount") + @") / ( " + escaper.Log10Function("2") + @" * {2})", 10) + @"FROM (SELECT (Count(*)) as pcount FROM {0} GROUP BY {1}) exp1"; StringBuilder columnsString = new StringBuilder(columns.Length * 10); bool first = true; foreach (var column in columns) { var escapedColumn = escaper.Escape(column); if (first) { columnsString.Append(escapedColumn); first = false; } else { columnsString.AppendFormat(", {0}", escapedColumn); } } var query = string.Format(sourceQuery, escaper.Escape(table), columnsString.ToString(), table.Cardinality); var res = table.QueryTable(query); if (res is DBNull) { return(0); } else { return(Math.Max(0, Convert.ToDouble(res))); } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); return(0); } }
/// <summary> /// Escape /// </summary> public static string Escape(this string value, IEscaper escaper) { if (escaper is null) { throw new ArgumentNullException(nameof(escaper)); } return(escaper.Escape(value)); }