From f67dd1e1b83fbdabb9f6b885d417c19a583473f1 Mon Sep 17 00:00:00 2001 From: Hossein Moein Date: Thu, 5 Sep 2024 13:25:25 -0400 Subject: [PATCH] Implemented get_view_before_times() --- docs/HTML/DataFrame.html | 4 + docs/HTML/get_data_at_times.html | 8 +- docs/HTML/get_data_before_times.html | 161 ++++++++++++++++++ include/DataFrame/DataFrame.h | 43 +++++ .../DataFrame/Internals/DataFrame_slice.tcc | 132 ++++++++++++++ test/dataframe_tester_4.cc | 35 ++++ 6 files changed, 379 insertions(+), 4 deletions(-) create mode 100644 docs/HTML/get_data_before_times.html diff --git a/docs/HTML/DataFrame.html b/docs/HTML/DataFrame.html index faa64698..023b3f45 100644 --- a/docs/HTML/DataFrame.html +++ b/docs/HTML/DataFrame.html @@ -362,6 +362,10 @@

API Reference with code samples &# get_data_at_times()
get_view_at_times()
+ + get_data_before_times()
get_view_before_times()
+ + get_data_by_idx( 2 )
get_view_by_idx( 2 )
diff --git a/docs/HTML/get_data_at_times.html b/docs/HTML/get_data_at_times.html index 0a371b35..8cd98811 100644 --- a/docs/HTML/get_data_at_times.html +++ b/docs/HTML/get_data_at_times.html @@ -53,9 +53,9 @@ This selects the rows using the index column at specified time. It returns another DataFrame with selected data indexed by DateTime. Self is unchanged.

- NOTE: The index column type must be DateTime or it won’t compile
+ NOTE: The index column type must be DateTime or it won't compile
- + Ts: List all the types of all data columns. A type should be specified in the list only once.
hour: Specified hour
minute: Specified minute
@@ -79,7 +79,7 @@ It behaves like get_data_at_times(), but it returns a View. A view is a DataFrame that is a reference to the original DataFrame. So if you modify anything in the view the original DataFrame will also be modified.

NOTE: There are certain operations that you cannot do with a view. For example, you cannot add/delete columns, etc.
- + Ts: List all the types of all data columns. A type should be specified in the list only once.
hour: Specified hour
minute: Specified minute
@@ -102,7 +102,7 @@ Same as above view, but it returns a const view. You can not change data in const views. But if the data is changed in the original DataFrame or through another view, it is reflected in the const view. - + Ts: List all the types of all data columns. A type should be specified in the list only once.
hour: Specified hour
minute: Specified minute
diff --git a/docs/HTML/get_data_before_times.html b/docs/HTML/get_data_before_times.html new file mode 100644 index 00000000..2f1a76f9 --- /dev/null +++ b/docs/HTML/get_data_before_times.html @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Signature Description Parameters
+

+template<typename ... Ts>
+DataFrame<DateTime, H>
+get_data_before_times(DateTime::HourType hour,  // 24 hour
+                      DateTime::MinuteType minute = 0,
+                      DateTime::SecondType second = 0,
+                      DateTime::MillisecondType msec = 0) const;
+        
+
+ This selects the rows using the index column that happen before the specified time. It returns another DataFrame with selected data indexed by DateTime. The specified times are excluded. Self is unchanged.

+ NOTE: The index column type must be DateTime or it won't compile
+
+ Ts: List all the types of all data columns. A type should be specified in the list only once.
+ hour: Specified hour
+ minute: Specified minute
+ second: Specified second
+ msec: Specified milli-second
+
+

+template<typename ... Ts>
+PtrView
+get_view_before_times(DateTime::HourType hour,  // 24 hour
+                      DateTime::MinuteType minute = 0,
+                      DateTime::SecondType second = 0,
+                      DateTime::MillisecondType msec = 0);
+        
+
+ It behaves like get_data_before_times(), but it returns a View. A view is a DataFrame that is a reference to the original DataFrame. So if you modify anything in the view the original DataFrame will also be modified.

+ NOTE: There are certain operations that you cannot do with a view. For example, you cannot add/delete columns, etc.
+
+ Ts: List all the types of all data columns. A type should be specified in the list only once.
+ hour: Specified hour
+ minute: Specified minute
+ second: Specified second
+ msec: Specified milli-second
+
+

+template<typename ... Ts>
+ConstPtrView
+get_view_before_times(DateTime::HourType hour,  // 24 hour
+                      DateTime::MinuteType minute = 0,
+                      DateTime::SecondType second = 0,
+                      DateTime::MillisecondType msec = 0) const;
+        
+
+ Same as above view, but it returns a const view. You can not change data in const views. But if the data is changed in the original DataFrame or through another view, it is reflected in the const view. + + Ts: List all the types of all data columns. A type should be specified in the list only once.
+ hour: Specified hour
+ minute: Specified minute
+ second: Specified second
+ msec: Specified milli-second
+
+ +
static void test_get_data_before_times()  {
+
+    std::cout << "\nTesting load_get_data_before_times( ) ..." << std::endl;
+
+    DTDataFrame df;
+
+    try  {
+        df.read("DT_Intraday.csv", io_format::csv2);
+    }
+    catch (const DataFrameError &ex)  {
+        std::cout << ex.what() << std::endl;
+    }
+
+    const auto  result = df.get_view_before_times<double, long>(1, 16);
+
+    assert(result.get_index().size() == 523);
+    assert(result.get_index()[0].date() == 19861116);
+    assert(result.get_index()[10].date() == 19861120);
+    assert(result.get_index()[500].date() == 19870615);
+    assert(result.get_index()[522].date() == 19870624);
+    assert(result.get_column<double>("dbl value").size() == 523);
+    assert(result.get_column<double>("dbl value")[0] == 11.0);
+    assert(result.get_column<double>("dbl value")[10] == 101.0);
+    assert(result.get_column<double>("dbl value")[500] == 4796.0);
+    assert(result.get_column<double>("dbl value")[522] == 4996.0);
+    assert(result.get_column<long>("lng value").size() == 523);
+    assert(result.get_column<long>("lng value")[0] == 220);
+    assert(result.get_column<long>("lng value")[10] == 2020);
+    assert(result.get_column<long>("lng value")[500] == 95920);
+    assert(result.get_column<long>("lng value")[522] == 99920);
+}
+
+ +
C++ DataFrame + + + + + diff --git a/include/DataFrame/DataFrame.h b/include/DataFrame/DataFrame.h index 9bf16345..c1883385 100644 --- a/include/DataFrame/DataFrame.h +++ b/include/DataFrame/DataFrame.h @@ -3716,6 +3716,49 @@ class DataFrame : public ThreadGranularity { DateTime::SecondType sc = 0, DateTime::MillisecondType msc = 0) const; + // This selects the rows using the index column that happen before the + // specified time. It returns another DataFrame with selected data indexed + // by DateTime. The specified times are excluded. Self is unchanged. + // + // NOTE: The index column type must be DateTime or it won’t compile + // + // Ts: + // List all the types of all data columns. A type should be specified in + // the list only once. + // hr: + // Specified hour + // mn: + // Specified minute + // sc: + // Specified second + // msc: + // Specified milli-second + // + template + [[nodiscard]] DataFrame> + get_data_before_times(DateTime::HourType hr, // 24 hour notation + DateTime::MinuteType mn = 0, + DateTime::SecondType sc = 0, + DateTime::MillisecondType msc = 0) const; + + // Same as get_view_before_times() above, but it returns a view + // + template + [[nodiscard]] PtrView + get_view_before_times(DateTime::HourType hr, // 24 hour notation + DateTime::MinuteType mn = 0, + DateTime::SecondType sc = 0, + DateTime::MillisecondType msc = 0); + + // Same as get_view_before_times() above, but it returns a const view + // + template + [[nodiscard]] ConstPtrView + get_view_before_times(DateTime::HourType hr, // 24 hour notation + DateTime::MinuteType mn = 0, + DateTime::SecondType sc = 0, + DateTime::MillisecondType msc = 0) const; + public: // Visitors // apply is a shortcut for a simple visit. It applies the func to every diff --git a/include/DataFrame/Internals/DataFrame_slice.tcc b/include/DataFrame/Internals/DataFrame_slice.tcc index 95839fe5..16b03dae 100644 --- a/include/DataFrame/Internals/DataFrame_slice.tcc +++ b/include/DataFrame/Internals/DataFrame_slice.tcc @@ -2478,6 +2478,9 @@ get_view_at_times(DateTime::HourType hr, DateTime::SecondType sc, DateTime::MillisecondType msc) { + static_assert(std::is_base_of::value, + "Index type must be DateTime to call get_view_at_times()"); + const size_type idx_s = indices_.size(); StlVecType col_indices; @@ -2501,6 +2504,9 @@ get_view_at_times(DateTime::HourType hr, DateTime::SecondType sc, DateTime::MillisecondType msc) const { + static_assert(std::is_base_of::value, + "Index type must be DateTime to call get_view_at_times()"); + const size_type idx_s = indices_.size(); StlVecType col_indices; @@ -2514,6 +2520,132 @@ get_view_at_times(DateTime::HourType hr, return (view_by_sel_common_(col_indices, idx_s)); } +// ---------------------------------------------------------------------------- + +template +template +DataFrame> +DataFrame:: +get_data_before_times(DateTime::HourType hr, + DateTime::MinuteType mn, + DateTime::SecondType sc, + DateTime::MillisecondType msc) const { + + static_assert( + std::is_base_of::value, + "Index type must be DateTime to call get_data_before_time()"); + + const size_type idx_s = indices_.size(); + StlVecType col_indices; + + col_indices.reserve(idx_s / 5); + for (size_type i = 0; i < idx_s; ++i) { + if (indices_[i].hour() < hr) { + col_indices.push_back(i); + } + else if (indices_[i].hour() == hr) { + if (indices_[i].minute() < mn) { + col_indices.push_back(i); + } + else if (indices_[i].minute() == mn) { + if (indices_[i].sec() < sc) { + col_indices.push_back(i); + } + else if (indices_[i].sec() == sc) { + if (indices_[i].msec() < msc) { + col_indices.push_back(i); + } + } + } + } + } + + return (data_by_sel_common_(col_indices, idx_s)); +} + +// ---------------------------------------------------------------------------- + +template +template +typename DataFrame::PtrView DataFrame:: +get_view_before_times(DateTime::HourType hr, + DateTime::MinuteType mn, + DateTime::SecondType sc, + DateTime::MillisecondType msc) { + + static_assert( + std::is_base_of::value, + "Index type must be DateTime to call get_view_before_times()"); + + const size_type idx_s = indices_.size(); + StlVecType col_indices; + + col_indices.reserve(idx_s / 5); + for (size_type i = 0; i < idx_s; ++i) { + if (indices_[i].hour() < hr) { + col_indices.push_back(i); + } + else if (indices_[i].hour() == hr) { + if (indices_[i].minute() < mn) { + col_indices.push_back(i); + } + else if (indices_[i].minute() == mn) { + if (indices_[i].sec() < sc) { + col_indices.push_back(i); + } + else if (indices_[i].sec() == sc) { + if (indices_[i].msec() < msc) { + col_indices.push_back(i); + } + } + } + } + } + + return (view_by_sel_common_(col_indices, idx_s)); +} + +// ---------------------------------------------------------------------------- + +template +template +typename DataFrame::ConstPtrView DataFrame:: +get_view_before_times(DateTime::HourType hr, + DateTime::MinuteType mn, + DateTime::SecondType sc, + DateTime::MillisecondType msc) const { + + static_assert( + std::is_base_of::value, + "Index type must be DateTime to call get_view_before_times()"); + + const size_type idx_s = indices_.size(); + StlVecType col_indices; + + col_indices.reserve(idx_s / 5); + for (size_type i = 0; i < idx_s; ++i) { + if (indices_[i].hour() < hr) { + col_indices.push_back(i); + } + else if (indices_[i].hour() == hr) { + if (indices_[i].minute() < mn) { + col_indices.push_back(i); + } + else if (indices_[i].minute() == mn) { + if (indices_[i].sec() < sc) { + col_indices.push_back(i); + } + else if (indices_[i].sec() == sc) { + if (indices_[i].msec() < msc) { + col_indices.push_back(i); + } + } + } + } + } + + return (view_by_sel_common_(col_indices, idx_s)); +} } // namespace hmdf diff --git a/test/dataframe_tester_4.cc b/test/dataframe_tester_4.cc index bff57450..a1ce9dc7 100644 --- a/test/dataframe_tester_4.cc +++ b/test/dataframe_tester_4.cc @@ -964,6 +964,40 @@ static void test_get_data_at_times() { // ---------------------------------------------------------------------------- +static void test_get_data_before_times() { + + std::cout << "\nTesting load_get_data_before_times( ) ..." << std::endl; + + DTDataFrame df; + + try { + df.read("DT_Intraday.csv", io_format::csv2); + } + catch (const DataFrameError &ex) { + std::cout << ex.what() << std::endl; + } + + const auto result = df.get_view_before_times(1, 16); + + assert(result.get_index().size() == 523); + assert(result.get_index()[0].date() == 19861116); + assert(result.get_index()[10].date() == 19861120); + assert(result.get_index()[500].date() == 19870615); + assert(result.get_index()[522].date() == 19870624); + assert(result.get_column("dbl value").size() == 523); + assert(result.get_column("dbl value")[0] == 11.0); + assert(result.get_column("dbl value")[10] == 101.0); + assert(result.get_column("dbl value")[500] == 4796.0); + assert(result.get_column("dbl value")[522] == 4996.0); + assert(result.get_column("lng value").size() == 523); + assert(result.get_column("lng value")[0] == 220); + assert(result.get_column("lng value")[10] == 2020); + assert(result.get_column("lng value")[500] == 95920); + assert(result.get_column("lng value")[522] == 99920); +} + +// ---------------------------------------------------------------------------- + int main(int, char *[]) { test_starts_with(); @@ -978,6 +1012,7 @@ int main(int, char *[]) { test_read_write_pairs(); test_difference(); test_get_data_at_times(); + test_get_data_before_times(); return (0); }