Back to Documentations

Signature Description Parameters
template<typename DF, typename ... Ts>
inline DF df_plus(const DF &lhs, const DF &rhs);
This is the global plus (+) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
template<typename DF, typename ... Ts>
inline DF df_minus(const DF &lhs, const DF &rhs);
This is the global minus (-) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
template<typename DF, typename ... Ts>
inline DF df_multiplies(const DF &lhs, const DF &rhs);
This is the global multiplication (*) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
template<typename DF, typename ... Ts>
inline DF df_divides(const DF &lhs, const DF &rhs);
This is the global division (/) operator between two DataFrames.
This arithmetic operator operates on the same-name and same-type columns in lhs and rhs. If the entry has the same index value, the operation will be applied.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
template<typename DF, typename ST, typename ... Ts>
inline DF scaler_df_plus(const DF &lhs, const ST &scaler);
This is the global plus (+) operator between a DataFrame and a scaler.
This arithmetic operator adds the scaler value to all the lhs columns. There will be a compile error, if there is a column in lhs for which this operation is not defined.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
ST: The type of the scaler value.
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
template<typename DF, typename ST, typename ... Ts>
inline DF scaler_df_minus(const DF &lhs, const ST &scaler);
This is the global minus (-) operator between a DataFrame and a scaler.
This arithmetic operator subtracts the scaler value from all the lhs columns. There will be a compile error, if there is a column in lhs for which this operation is not defined.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
ST: The type of the scaler value.
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
template<typename DF, typename ST, typename ... Ts>
inline DF scaler_df_multiplies(const DF &lhs, const ST &scaler);
This is the global multiplication (*) operator between a DataFrame and a scaler.
This arithmetic operator multiplies all the lhs columns by the scaler value. There will be a compile error, if there is a column in lhs for which this operation is not defined.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
ST: The type of the scaler value.
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
template<typename DF, typename ST, typename ... Ts>
inline DF scaler_df_divides(const DF &lhs, const ST &scaler);
This is the global division (/) operator between a DataFrame and a scaler.
This arithmetic operator divides all the lhs columns by the scaler value. There will be a compile error, if there is a column in lhs for which this operation is not defined.
It returns a new DataFrame which contains the result of the operations.
Ts: The list of types for all columns. A type should be specified only once.
DF: The DataFrame type involved here
ST: The type of the scaler value.
lhs: The left-hand-side DataFrame
rhs: The right-hand-side DataFrame
static void test_dataframe_friend_plus_operator()  {

    std::cout << "\nTesting DataFrame friend plus operator ..." << std::endl;

    MyDataFrame df1;
    MyDataFrame df2;

    try  {
        df1.read("sample_data.csv");
        df2.read("sample_data.csv");
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }

    MyDataFrame result = df_plus<MyDataFrame, unsigned long, int, double, std::string, bool>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
}

// -----------------------------------------------------------------------------

static void test_dataframe_friend_minus_operator()  {

    std::cout << "\nTesting DataFrame friend minus operator ..." << std::endl;

    MyDataFrame df1;
    MyDataFrame df2;

    try  {
        df1.read("sample_data.csv");
        df2.read("sample_data.csv");
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }

    // Notice I am omitting std::string here, since minus is not defined for
    // std::string, and hence it won't compile
    MyDataFrame result = df_minus<MyDataFrame, unsigned long, int, double, bool>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, unsigned long, double, std::string, bool>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, unsigned long, double, bool>(std::cout);
}

// -----------------------------------------------------------------------------

static void test_dataframe_friend_multiplies_operator()  {

    std::cout << "\nTesting DataFrame friend multiplies operator ..."
              << std::endl;

    std::vector<unsigned long>  idx1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 25, 40, 55 };
    std::vector<unsigned long>  idx2 = { 1, 2, 3, 4, 5, 8, 9, 22, 25, 40 };
    std::vector<double>         d1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<double>         d2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    std::vector<double>         s1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<int>            s2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    MyDataFrame df1;
    MyDataFrame df2;

    df1.load_data(std::move(idx1), std::make_pair("dbl_col", d1), std::make_pair("same_name", s1));
    df2.load_data(std::move(idx2), std::make_pair("dbl_col", d2), std::make_pair("same_name", s2));

    MyDataFrame result = df_multiplies<MyDataFrame, int, double>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, double>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, double>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, double>(std::cout);
}

// -----------------------------------------------------------------------------

static void test_dataframe_friend_divides_operator()  {

    std::cout << "\nTesting DataFrame friend divides operator ..." << std::endl;

    std::vector<unsigned long>  idx1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 25, 40, 55 };
    std::vector<unsigned long>  idx2 = { 1, 2, 3, 4, 5, 8, 9, 22, 25, 40 };
    std::vector<double>         d1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<double>         d2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    std::vector<double>         s1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    std::vector<int>            s2 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    MyDataFrame df1;
    MyDataFrame df2;

    df1.load_data(std::move(idx1), std::make_pair("dbl_col", d1), std::make_pair("same_name", s1));
    df2.load_data(std::move(idx2), std::make_pair("dbl_col", d2), std::make_pair("same_name", s2));

    MyDataFrame result = df_divides<MyDataFrame, int, double>(df1, df2);

    std::cout << "Original DF1:" << std::endl;
    df1.write<std::ostream, int, double>(std::cout);
    std::cout << "Original DF2:" << std::endl;
    df2.write<std::ostream, int, double>(std::cout);
    std::cout << "Result DF:" << std::endl;
    result.write<std::ostream, int, double>(std::cout);
}
// -----------------------------------------------------------------------------

static void test_dataframe_friend_scaler_operator()  {

    std::cout << "\nTesting DataFrame friend scaler operator ..." << std::endl;

    StrDataFrame    df;

    try  {
        df.read("data/SHORT_IBM.csv", io_format::csv2);
    }
    catch (const DataFrameError &ex)  {
        std::cout << ex.what() << std::endl;
    }

    const auto  col_size = df.get_index().size();
    const auto  &df_idx = df.get_index();
    const auto  &df_close = df.get_column<double>("IBM_Close");
    const auto  &df_volume = df.get_column<long>("IBM_Volume");

    StrDataFrame    plus_result = scaler_df_plus<StrDataFrame, double, long, double>(df, 10.5);
    const auto      &plus_idx = plus_result.get_index();
    const auto      &plus_close = plus_result.get_column<double>("IBM_Close");
    const auto      &plus_volume = plus_result.get_column<long>("IBM_Volume");

    for (std::size_t i = 0; i < col_size; ++i)  {
        assert(plus_idx[i] == df_idx[i]);
        assert((plus_close[i] == (df_close[i] + 10.5)));
        assert((plus_volume[i] == (df_volume[i] + 10L)));
    }

    const int       value = 10;
    StrDataFrame    minus_result = scaler_df_minus<StrDataFrame, int, long, double>(df, value);
    const auto      &minus_idx = minus_result.get_index();
    const auto      &minus_close = minus_result.get_column<double>("IBM_Close");
    const auto      &minus_volume = minus_result.get_column<long>("IBM_Volume");

    for (std::size_t i = 0; i < col_size; ++i)  {
        assert(minus_idx[i] == df_idx[i]);
        assert((minus_close[i] == (df_close[i] - value)));
        assert((minus_volume[i] == (df_volume[i] - value)));
    }

    StrDataFrame    multi_result = scaler_df_multiplies<StrDataFrame, double, long, double>(df, 5.0);
    const auto      &multi_idx = multi_result.get_index();
    const auto      &multi_close = multi_result.get_column<double>("IBM_Close");
    const auto      &multi_volume = multi_result.get_column<long>("IBM_Volume");

    for (std::size_t i = 0; i < col_size; ++i)  {
        assert(multi_idx[i] == df_idx[i]);
        assert((multi_close[i] == (df_close[i] * 5.0)));
        assert((multi_volume[i] == (df_volume[i] * 5L)));
    }

    StrDataFrame    div_result = scaler_df_divides<StrDataFrame, long, long, double>(df, 10L);
    const auto      &div_idx = div_result.get_index();
    const auto      &div_close = div_result.get_column<double>("IBM_Close");
    const auto      &div_volume = div_result.get_column<long>("IBM_Volume");

    for (std::size_t i = 0; i < col_size; ++i)  {
        assert(div_idx[i] == df_idx[i]);
        assert((div_close[i] == (df_close[i] / 10.0)));
        assert((div_volume[i] == (df_volume[i] / 10L)));
    }
}

C++ DataFrame