@@ -40,13 +40,14 @@ static Column* reduce_first(Column* arg, const Groupby& groupby) {
4040 return Column::new_data_column (arg->stype (), 0 );
4141 }
4242 size_t ngrps = groupby.ngroups ();
43- arr32_t indices (ngrps);
44- // TODO: avoid copy (by allowing RowIndex to be created from a MemoryRange)
45- std::memcpy (indices.data (), groupby.offsets_r (), ngrps * sizeof (int32_t ));
46- RowIndex ri = RowIndex::from_array32 (std::move (indices), true );
47- Column* res = arg->shallowcopy (ri);
48- res->reify ();
49- return res;
43+ // groupby.offsets array has length `ngrps + 1` and contains offsets of the
44+ // beginning of each group. We will take this array and reinterpret it as a
45+ // RowIndex (taking only the first `ngrps` elements). Applying this rowindex
46+ // to the column will produce the vector of first elements in that column.
47+ arr32_t indices (ngrps, groupby.offsets_r ());
48+ RowIndex ri = RowIndex::from_array32 (std::move (indices), true )
49+ .uplift (arg->rowindex ());
50+ return arg->shallowcopy (ri);
5051}
5152
5253
@@ -65,11 +66,12 @@ static void sum_skipna(const int32_t* groups, int32_t grp, void** params) {
6566 OT sum = 0 ;
6667 int32_t row0 = groups[grp];
6768 int32_t row1 = groups[grp + 1 ];
68- for (int32_t i = row0; i < row1; ++i) {
69- IT x = inputs[i];
70- if (ISNA<IT>(x)) continue ;
71- sum += static_cast <OT>(x);
72- }
69+ col0->rowindex ().strided_loop (row0, row1, 1 ,
70+ [&](int64_t i) {
71+ IT x = inputs[i];
72+ if (!ISNA<IT>(x))
73+ sum += static_cast <OT>(x);
74+ });
7375 outputs[grp] = sum;
7476}
7577
@@ -90,15 +92,16 @@ static void mean_skipna(const int32_t* groups, int32_t grp, void** params) {
9092 OT delta = 0 ;
9193 int32_t row0 = groups[grp];
9294 int32_t row1 = groups[grp + 1 ];
93- for (int32_t i = row0; i < row1; ++i) {
94- IT x = inputs[i];
95- if (ISNA<IT>(x)) continue ;
96- OT y = static_cast <OT>(x) - delta;
97- OT t = sum + y;
98- delta = (t - sum) - y;
99- sum = t;
100- cnt++;
101- }
95+ col0->rowindex ().strided_loop (row0, row1, 1 ,
96+ [&](int64_t i) {
97+ IT x = inputs[i];
98+ if (ISNA<IT>(x)) return ;
99+ OT y = static_cast <OT>(x) - delta;
100+ OT t = sum + y;
101+ delta = (t - sum) - y;
102+ sum = t;
103+ cnt++;
104+ });
102105 outputs[grp] = cnt == 0 ? GETNA<OT>() : sum / cnt;
103106}
104107
@@ -120,15 +123,16 @@ static void stdev_skipna(const int32_t* groups, int32_t grp, void** params) {
120123 int64_t cnt = 0 ;
121124 int32_t row0 = groups[grp];
122125 int32_t row1 = groups[grp + 1 ];
123- for (int32_t i = row0; i < row1; ++i) {
124- IT x = inputs[i];
125- if (ISNA<IT>(x)) continue ;
126- cnt++;
127- OT t1 = x - mean;
128- mean += t1 / cnt;
129- OT t2 = x - mean;
130- m2 += t1 * t2;
131- }
126+ col0->rowindex ().strided_loop (row0, row1, 1 ,
127+ [&](int64_t i) {
128+ IT x = inputs[i];
129+ if (ISNA<IT>(x)) return ;
130+ cnt++;
131+ OT t1 = x - mean;
132+ mean += t1 / cnt;
133+ OT t2 = x - mean;
134+ m2 += t1 * t2;
135+ });
132136 outputs[grp] = cnt <= 1 ? GETNA<OT>() : std::sqrt (m2 / (cnt - 1 ));
133137}
134138
@@ -147,12 +151,13 @@ static void min_skipna(const int32_t* groups, int32_t grp, void** params) {
147151 T res = infinity<T>();
148152 int32_t row0 = groups[grp];
149153 int32_t row1 = groups[grp + 1 ];
150- for (int32_t i = row0; i < row1; ++i) {
151- T x = inputs[i];
152- if (!ISNA<T>(x) && x < res) {
153- res = x;
154- }
155- }
154+ col0->rowindex ().strided_loop (row0, row1, 1 ,
155+ [&](int64_t i) {
156+ T x = inputs[i];
157+ if (!ISNA<T>(x) && x < res) {
158+ res = x;
159+ }
160+ });
156161 outputs[grp] = res;
157162}
158163
@@ -171,12 +176,13 @@ static void max_skipna(const int32_t* groups, int32_t grp, void** params) {
171176 T res = -infinity<T>();
172177 int32_t row0 = groups[grp];
173178 int32_t row1 = groups[grp + 1 ];
174- for (int32_t i = row0; i < row1; ++i) {
175- T x = inputs[i];
176- if (!ISNA<T>(x) && x > res) {
177- res = x;
178- }
179- }
179+ col0->rowindex ().strided_loop (row0, row1, 1 ,
180+ [&](int64_t i) {
181+ T x = inputs[i];
182+ if (!ISNA<T>(x) && x > res) {
183+ res = x;
184+ }
185+ });
180186 outputs[grp] = res;
181187}
182188
0 commit comments