Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs @ 17181

Last change on this file since 17181 was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

File size: 13.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HEAL.Attic;
29using HeuristicLab.Problems.DataAnalysis;
30
31namespace HeuristicLab.DataPreprocessing {
32  [Item("FilteredPreprocessingData", "Represents filtered data used for preprocessing.")]
33  [StorableType("26BAE57C-A102-483D-8A09-AEC7132FD837")]
34  public sealed class FilteredPreprocessingData : NamedItem, IFilteredPreprocessingData {
35
36    [Storable]
37    private readonly IPreprocessingData originalData;
38    [Storable]
39    private IPreprocessingData filteredData;
40
41    public IPreprocessingData ActiveData {
42      get { return IsFiltered ? filteredData : originalData; }
43    }
44
45    #region Constructor, Cloning & Persistence
46    public FilteredPreprocessingData(IPreprocessingData preprocessingData)
47      : base() {
48      originalData = preprocessingData;
49      filteredData = null;
50    }
51
52    private FilteredPreprocessingData(FilteredPreprocessingData original, Cloner cloner)
53      : base(original, cloner) {
54      originalData = original.originalData;
55      filteredData = original.filteredData;
56    }
57    public override IDeepCloneable Clone(Cloner cloner) {
58      return new FilteredPreprocessingData(this, cloner);
59    }
60
61    [StorableConstructor]
62    private FilteredPreprocessingData(StorableConstructorFlag _) : base(_) { }
63    #endregion
64
65    #region Cells
66    public bool IsCellEmpty(int columnIndex, int rowIndex) {
67      return ActiveData.IsCellEmpty(columnIndex, rowIndex);
68    }
69
70    public T GetCell<T>(int columnIndex, int rowIndex) {
71      return ActiveData.GetCell<T>(columnIndex, rowIndex);
72    }
73
74    public void SetCell<T>(int columnIndex, int rowIndex, T value) {
75      if (IsFiltered)
76        throw new InvalidOperationException("SetValues not possible while data is filtered");
77      originalData.SetCell<T>(columnIndex, rowIndex, value);
78    }
79
80    public string GetCellAsString(int columnIndex, int rowIndex) {
81      return ActiveData.GetCellAsString(columnIndex, rowIndex);
82    }
83
84    public IList<T> GetValues<T>(int columnIndex, bool considerSelection) {
85      return ActiveData.GetValues<T>(columnIndex, considerSelection);
86    }
87
88    public void SetValues<T>(int columnIndex, IList<T> values) {
89      if (IsFiltered)
90        throw new InvalidOperationException("SetValues not possible while data is filtered");
91
92      originalData.SetValues<T>(columnIndex, values);
93    }
94
95    public bool SetValue(string value, int columnIndex, int rowIndex) {
96      if (IsFiltered)
97        throw new InvalidOperationException("SetValue not possible while data is filtered");
98      return originalData.SetValue(value, columnIndex, rowIndex);
99    }
100
101    public int Columns {
102      get { return ActiveData.Columns; }
103    }
104
105    public int Rows {
106      get { return ActiveData.Rows; }
107    }
108    #endregion
109
110    #region Rows
111    public void InsertRow(int rowIndex) {
112      if (IsFiltered)
113        throw new InvalidOperationException("InsertRow not possible while data is filtered");
114
115      originalData.InsertRow(rowIndex);
116    }
117
118    public void DeleteRow(int rowIndex) {
119      if (IsFiltered)
120        throw new InvalidOperationException("DeleteRow not possible while data is filtered");
121
122      originalData.DeleteRow(rowIndex);
123    }
124
125    public void DeleteRowsWithIndices(IEnumerable<int> rows) {
126      if (IsFiltered)
127        throw new InvalidOperationException("DeleteRowsWithIndices not possible while data is filtered");
128
129      originalData.DeleteRowsWithIndices(rows);
130    }
131
132    public void InsertColumn<T>(string variableName, int columnIndex) {
133      if (IsFiltered)
134        throw new InvalidOperationException("InsertColumn not possible while data is filtered");
135
136      originalData.InsertColumn<T>(variableName, columnIndex);
137    }
138
139    public void DeleteColumn(int columnIndex) {
140      if (IsFiltered)
141        throw new InvalidOperationException("DeleteColumn not possible while data is filtered");
142      originalData.DeleteColumn(columnIndex);
143    }
144
145    public void RenameColumn(int columnIndex, string name) {
146      if (IsFiltered)
147        throw new InvalidOperationException("RenameColumn not possible while data is filtered");
148      originalData.RenameColumn(columnIndex, name);
149    }
150
151    public void RenameColumns(IList<string> names) {
152      if (IsFiltered)
153        throw new InvalidOperationException("RenameColumns not possible while data is filtered");
154      originalData.RenameColumns(names);
155    }
156
157    public bool AreAllStringColumns(IEnumerable<int> columnIndices) {
158      return originalData.AreAllStringColumns(columnIndices);
159    }
160    #endregion
161
162    #region Variables
163    public IEnumerable<string> VariableNames {
164      get { return ActiveData.VariableNames; }
165    }
166    public IEnumerable<string> GetDoubleVariableNames() {
167      return originalData.GetDoubleVariableNames();
168    }
169    public string GetVariableName(int columnIndex) {
170      return ActiveData.GetVariableName(columnIndex);
171    }
172
173    public int GetColumnIndex(string variableName) {
174      return ActiveData.GetColumnIndex(variableName);
175    }
176
177    public bool VariableHasType<T>(int columnIndex) {
178      return originalData.VariableHasType<T>(columnIndex);
179    }
180
181    public Type GetVariableType(int columnIndex) {
182      return ActiveData.GetVariableType(columnIndex);
183    }
184
185    public IList<string> InputVariables {
186      get { return ActiveData.InputVariables; }
187    }
188
189    public string TargetVariable {
190      get { return ActiveData.TargetVariable; }
191    } // optional
192    #endregion
193
194    #region Partitions
195    public IntRange TrainingPartition {
196      get { return originalData.TrainingPartition; }
197    }
198
199    public IntRange TestPartition {
200      get { return originalData.TestPartition; }
201    }
202    #endregion
203
204    #region Transformations
205    public IList<ITransformation> Transformations {
206      get { return originalData.Transformations; }
207    }
208    #endregion
209
210    #region Validation
211    public bool Validate(string value, out string errorMessage, int columnIndex) {
212      return originalData.Validate(value, out errorMessage, columnIndex);
213    }
214    #endregion
215
216    #region Import & Export
217    public void Import(IDataAnalysisProblemData problemData) {
218      if (IsFiltered)
219        throw new InvalidOperationException("Import not possible while data is filtered");
220      originalData.Import(problemData);
221    }
222
223    public Dataset ExportToDataset() {
224      return originalData.ExportToDataset();
225    }
226    #endregion
227
228    #region Selection
229    public IDictionary<int, IList<int>> Selection {
230      get { return originalData.Selection; }
231      set { originalData.Selection = value; }
232    }
233
234    public void ClearSelection() {
235      originalData.ClearSelection();
236    }
237
238    public event EventHandler SelectionChanged {
239      add { originalData.SelectionChanged += value; }
240      remove { originalData.SelectionChanged -= value; }
241    }
242    #endregion
243
244    #region Transactions
245    public event DataPreprocessingChangedEventHandler Changed {
246      add { originalData.Changed += value; }
247      remove { originalData.Changed -= value; }
248    }
249
250    public bool IsUndoAvailable {
251      get { return IsFiltered ? false : originalData.IsUndoAvailable; }
252    }
253
254    public void Undo() {
255      if (IsFiltered)
256        throw new InvalidOperationException("Undo not possible while data is filtered");
257
258      originalData.Undo();
259    }
260
261    public void InTransaction(Action action, DataPreprocessingChangedEventType type = DataPreprocessingChangedEventType.Any) {
262      if (IsFiltered)
263        throw new InvalidOperationException("Transaction not possible while data is filtered");
264      originalData.InTransaction(action, type);
265    }
266
267    public void BeginTransaction(DataPreprocessingChangedEventType type) {
268      if (IsFiltered)
269        throw new InvalidOperationException("Transaction not possible while data is filtered");
270      originalData.BeginTransaction(type);
271    }
272
273    public void EndTransaction() {
274      originalData.EndTransaction();
275    }
276    #endregion
277
278    #region Statistics
279    public T GetMin<T>(int columnIndex, bool considerSelection = false, T emptyValue = default(T)) {
280      return ActiveData.GetMin<T>(columnIndex, considerSelection, emptyValue);
281    }
282    public T GetMax<T>(int columnIndex, bool considerSelection = false, T emptyValue = default(T)) {
283      return ActiveData.GetMax<T>(columnIndex, considerSelection, emptyValue);
284    }
285    public T GetMean<T>(int columnIndex, bool considerSelection = false, T emptyValue = default(T)) {
286      return ActiveData.GetMean<T>(columnIndex, considerSelection, emptyValue);
287    }
288    public T GetMedian<T>(int columnIndex, bool considerSelection = false, T emptyValue = default(T)) where T : IComparable<T> {
289      return ActiveData.GetMedian<T>(columnIndex, considerSelection, emptyValue);
290    }
291    public T GetMode<T>(int columnIndex, bool considerSelection = false, T emptyValue = default(T)) where T : IEquatable<T> {
292      return ActiveData.GetMode<T>(columnIndex, considerSelection, emptyValue);
293    }
294    public T GetStandardDeviation<T>(int columnIndex, bool considerSelection = false, T emptyValue = default(T)) {
295      return ActiveData.GetStandardDeviation<T>(columnIndex, considerSelection, emptyValue);
296    }
297    public T GetVariance<T>(int columnIndex, bool considerSelection = false, T emptyValue = default(T)) {
298      return ActiveData.GetVariance<T>(columnIndex, considerSelection, emptyValue);
299    }
300    public T GetQuantile<T>(double alpha, int columnIndex, bool considerSelection = false, T emptyValue = default(T)) where T : IComparable<T> {
301      return ActiveData.GetQuantile<T>(alpha, columnIndex, considerSelection, emptyValue);
302    }
303    public int GetDistinctValues<T>(int columnIndex, bool considerSelection = false) {
304      return ActiveData.GetDistinctValues<T>(columnIndex, considerSelection);
305    }
306
307    public int GetMissingValueCount() {
308      return ActiveData.GetMissingValueCount();
309    }
310    public int GetMissingValueCount(int columnIndex) {
311      return ActiveData.GetMissingValueCount(columnIndex);
312    }
313    public int GetRowMissingValueCount(int rowIndex) {
314      return ActiveData.GetRowMissingValueCount(rowIndex);
315    }
316    #endregion
317
318    #region Filters
319    public void SetFilter(bool[] remainingRows) {
320      filteredData = (IPreprocessingData)originalData.Clone();
321      filteredData.InTransaction(() => {
322        var remainingIndices = Enumerable.Range(0, remainingRows.Length).Where(x => remainingRows[x]);
323
324        foreach (var v in filteredData.VariableNames) {
325          var ci = filteredData.GetColumnIndex(v);
326          if (filteredData.VariableHasType<double>(ci)) {
327            var values = filteredData.GetValues<double>(ci);
328            var filteredValues = remainingIndices.Select(x => values[x]).ToList();
329            filteredData.SetValues(ci, filteredValues);
330          } else if (filteredData.VariableHasType<DateTime>(ci)) {
331            var values = filteredData.GetValues<DateTime>(ci);
332            var filteredValues = remainingIndices.Select(x => values[x]).ToList();
333            filteredData.SetValues(ci, filteredValues);
334          } else if (filteredData.VariableHasType<string>(ci)) {
335            var values = filteredData.GetValues<string>(ci);
336            var filteredValues = remainingIndices.Select(x => values[x]).ToList();
337            filteredData.SetValues(ci, filteredValues);
338          }
339        }
340      });
341      OnFilterChanged();
342    }
343
344    public void PersistFilter() {
345      originalData.InTransaction(() => {
346        for (int i = 0; i < filteredData.Columns; ++i) {
347          if (filteredData.VariableHasType<double>(i)) {
348            originalData.SetValues<double>(i, filteredData.GetValues<double>(i));
349          } else if (filteredData.VariableHasType<string>(i)) {
350            originalData.SetValues<string>(i, filteredData.GetValues<string>(i));
351          } else if (filteredData.VariableHasType<DateTime>(i)) {
352            originalData.SetValues<DateTime>(i, filteredData.GetValues<DateTime>(i));
353          } else {
354            throw new ArgumentException("Data types of columns do not match");
355          }
356        }
357      });
358      ResetFilter();
359    }
360
361    public void ResetFilter() {
362      filteredData = null;
363      OnFilterChanged();
364    }
365
366    public bool IsFiltered {
367      get { return filteredData != null; }
368    }
369
370    public event EventHandler FilterChanged;
371
372    private void OnFilterChanged() {
373      if (FilterChanged != null) {
374        FilterChanged(this, new EventArgs());
375      }
376    }
377    #endregion
378  }
379}
Note: See TracBrowser for help on using the repository browser.