Skip to content

Commit c1237f2

Browse files
jbrockmendeljreback
authored andcommitted
Use pandas_datetimestruct instead of date_info (#19874)
1 parent fb54f40 commit c1237f2

File tree

4 files changed

+178
-226
lines changed

4 files changed

+178
-226
lines changed

pandas/_libs/src/period_helper.c

+44-115
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,12 @@ static npy_int64 daytime_conversion_factor_matrix[7][7] = {
8989
{0, 0, 0, 0, 0, 1, 1000},
9090
{0, 0, 0, 0, 0, 0, 1}};
9191

92-
PANDAS_INLINE int max_value(int a, int b) { return a > b ? a : b; }
92+
int max_value(int a, int b) { return a > b ? a : b; }
9393

9494
PANDAS_INLINE int min_value(int a, int b) { return a < b ? a : b; }
9595

9696
PANDAS_INLINE int get_freq_group(int freq) { return (freq / 1000) * 1000; }
9797

98-
PANDAS_INLINE int get_freq_group_index(int freq) { return freq / 1000; }
99-
10098

10199
npy_int64 get_daytime_conversion_factor(int from_index, int to_index) {
102100
int row = min_value(from_index, to_index);
@@ -227,16 +225,6 @@ static npy_int64 asfreq_DTtoB(npy_int64 ordinal, asfreq_info *af_info) {
227225
return DtoB(&dinfo, roll_back, ordinal);
228226
}
229227

230-
// all intra day calculations are now done within one function
231-
static npy_int64 asfreq_DownsampleWithinDay(npy_int64 ordinal,
232-
asfreq_info *af_info) {
233-
return downsample_daytime(ordinal, af_info);
234-
}
235-
236-
static npy_int64 asfreq_UpsampleWithinDay(npy_int64 ordinal,
237-
asfreq_info *af_info) {
238-
return upsample_daytime(ordinal, af_info);
239-
}
240228
//************ FROM BUSINESS ***************
241229

242230
static npy_int64 asfreq_BtoDT(npy_int64 ordinal, asfreq_info *af_info) {
@@ -288,26 +276,26 @@ static npy_int64 asfreq_WtoW(npy_int64 ordinal, asfreq_info *af_info) {
288276
static npy_int64 asfreq_WtoB(npy_int64 ordinal, asfreq_info *af_info) {
289277
struct date_info dinfo;
290278
npy_int64 unix_date = asfreq_WtoDT(ordinal, af_info);
279+
291280
int roll_back = af_info->is_end;
292281
dInfoCalc_SetFromAbsDate(&dinfo, unix_date);
293-
294282
return DtoB(&dinfo, roll_back, unix_date);
295283
}
296284

297285
//************ FROM MONTHLY ***************
298-
static void MtoD_ym(npy_int64 ordinal, int *y, int *m) {
299-
*y = floordiv(ordinal, 12) + 1970;
300-
*m = mod_compat(ordinal, 12) + 1;
286+
static void MtoD_ym(npy_int64 ordinal, int *year, int *month) {
287+
*year = floordiv(ordinal, 12) + 1970;
288+
*month = mod_compat(ordinal, 12) + 1;
301289
}
302290

303291
static npy_int64 asfreq_MtoDT(npy_int64 ordinal, asfreq_info *af_info) {
304292
npy_int64 unix_date;
305-
int y, m;
293+
int year, month;
306294

307295
ordinal += af_info->is_end;
308-
MtoD_ym(ordinal, &y, &m);
309-
unix_date = unix_date_from_ymd(y, m, 1);
296+
MtoD_ym(ordinal, &year, &month);
310297

298+
unix_date = unix_date_from_ymd(year, month, 1);
311299
unix_date -= af_info->is_end;
312300
return upsample_daytime(unix_date, af_info);
313301
}
@@ -327,38 +315,37 @@ static npy_int64 asfreq_MtoW(npy_int64 ordinal, asfreq_info *af_info) {
327315
static npy_int64 asfreq_MtoB(npy_int64 ordinal, asfreq_info *af_info) {
328316
struct date_info dinfo;
329317
npy_int64 unix_date = asfreq_MtoDT(ordinal, af_info);
330-
int roll_back = af_info->is_end;
331318

319+
int roll_back = af_info->is_end;
332320
dInfoCalc_SetFromAbsDate(&dinfo, unix_date);
333-
334321
return DtoB(&dinfo, roll_back, unix_date);
335322
}
336323

337324
//************ FROM QUARTERLY ***************
338325

339-
static void QtoD_ym(npy_int64 ordinal, int *y, int *m, asfreq_info *af_info) {
340-
*y = floordiv(ordinal, 4) + 1970;
341-
*m = mod_compat(ordinal, 4) * 3 + 1;
326+
static void QtoD_ym(npy_int64 ordinal, int *year, int *month,
327+
asfreq_info *af_info) {
328+
*year = floordiv(ordinal, 4) + 1970;
329+
*month = mod_compat(ordinal, 4) * 3 + 1;
342330

343331
if (af_info->from_q_year_end != 12) {
344-
*m += af_info->from_q_year_end;
345-
if (*m > 12) {
346-
*m -= 12;
332+
*month += af_info->from_q_year_end;
333+
if (*month > 12) {
334+
*month -= 12;
347335
} else {
348-
*y -= 1;
336+
*year -= 1;
349337
}
350338
}
351339
}
352340

353341
static npy_int64 asfreq_QtoDT(npy_int64 ordinal, asfreq_info *af_info) {
354342
npy_int64 unix_date;
355-
int y, m;
343+
int year, month;
356344

357345
ordinal += af_info->is_end;
358-
QtoD_ym(ordinal, &y, &m, af_info);
359-
360-
unix_date = unix_date_from_ymd(y, m, 1);
346+
QtoD_ym(ordinal, &year, &month, af_info);
361347

348+
unix_date = unix_date_from_ymd(year, month, 1);
362349
unix_date -= af_info->is_end;
363350
return upsample_daytime(unix_date, af_info);
364351
}
@@ -382,29 +369,39 @@ static npy_int64 asfreq_QtoW(npy_int64 ordinal, asfreq_info *af_info) {
382369
static npy_int64 asfreq_QtoB(npy_int64 ordinal, asfreq_info *af_info) {
383370
struct date_info dinfo;
384371
npy_int64 unix_date = asfreq_QtoDT(ordinal, af_info);
385-
int roll_back = af_info->is_end;
386372

373+
int roll_back = af_info->is_end;
387374
dInfoCalc_SetFromAbsDate(&dinfo, unix_date);
388-
389375
return DtoB(&dinfo, roll_back, unix_date);
390376
}
391377

392378
//************ FROM ANNUAL ***************
393379

394-
static npy_int64 asfreq_AtoDT(npy_int64 ordinal, asfreq_info *af_info) {
395-
npy_int64 unix_date;
380+
static void AtoD_ym(npy_int64 ordinal, int *year, int *month,
381+
asfreq_info *af_info) {
382+
*year = ordinal + 1970;
383+
*month = 1;
396384

397-
// start from 1970
398-
npy_int64 year = ordinal + 1970;
399-
400-
int month = (af_info->from_a_year_end % 12) + 1;
401385
if (af_info->from_a_year_end != 12) {
402-
year -= 1;
386+
*month += af_info->from_a_year_end;
387+
if (*month > 12) {
388+
// This case is never reached, but is kept for symmetry
389+
// with QtoD_ym
390+
*month -= 12;
391+
} else {
392+
*year -= 1;
393+
}
403394
}
395+
}
404396

405-
year += af_info->is_end;
406-
unix_date = unix_date_from_ymd(year, month, 1);
397+
static npy_int64 asfreq_AtoDT(npy_int64 ordinal, asfreq_info *af_info) {
398+
npy_int64 unix_date;
399+
int year, month;
400+
401+
ordinal += af_info->is_end;
402+
AtoD_ym(ordinal, &year, &month, af_info);
407403

404+
unix_date = unix_date_from_ymd(year, month, 1);
408405
unix_date -= af_info->is_end;
409406
return upsample_daytime(unix_date, af_info);
410407
}
@@ -428,9 +425,9 @@ static npy_int64 asfreq_AtoW(npy_int64 ordinal, asfreq_info *af_info) {
428425
static npy_int64 asfreq_AtoB(npy_int64 ordinal, asfreq_info *af_info) {
429426
struct date_info dinfo;
430427
npy_int64 unix_date = asfreq_AtoDT(ordinal, af_info);
428+
431429
int roll_back = af_info->is_end;
432430
dInfoCalc_SetFromAbsDate(&dinfo, unix_date);
433-
434431
return DtoB(&dinfo, roll_back, unix_date);
435432
}
436433

@@ -443,57 +440,6 @@ static npy_int64 no_op(npy_int64 ordinal, asfreq_info *af_info) {
443440

444441
// end of frequency specific conversion routines
445442

446-
static int calc_a_year_end(int freq, int group) {
447-
int result = (freq - group) % 12;
448-
if (result == 0) {
449-
return 12;
450-
} else {
451-
return result;
452-
}
453-
}
454-
455-
static int calc_week_end(int freq, int group) { return freq - group; }
456-
457-
void get_asfreq_info(int fromFreq, int toFreq, char relation,
458-
asfreq_info *af_info) {
459-
int fromGroup = get_freq_group(fromFreq);
460-
int toGroup = get_freq_group(toFreq);
461-
462-
if (relation == 'E') {
463-
af_info->is_end = 1;
464-
} else {
465-
af_info->is_end = 0;
466-
}
467-
468-
af_info->intraday_conversion_factor = get_daytime_conversion_factor(
469-
get_freq_group_index(max_value(fromGroup, FR_DAY)),
470-
get_freq_group_index(max_value(toGroup, FR_DAY)));
471-
472-
switch (fromGroup) {
473-
case FR_WK:
474-
af_info->from_week_end = calc_week_end(fromFreq, fromGroup);
475-
break;
476-
case FR_ANN:
477-
af_info->from_a_year_end = calc_a_year_end(fromFreq, fromGroup);
478-
break;
479-
case FR_QTR:
480-
af_info->from_q_year_end = calc_a_year_end(fromFreq, fromGroup);
481-
break;
482-
}
483-
484-
switch (toGroup) {
485-
case FR_WK:
486-
af_info->to_week_end = calc_week_end(toFreq, toGroup);
487-
break;
488-
case FR_ANN:
489-
af_info->to_a_year_end = calc_a_year_end(toFreq, toGroup);
490-
break;
491-
case FR_QTR:
492-
af_info->to_q_year_end = calc_a_year_end(toFreq, toGroup);
493-
break;
494-
}
495-
}
496-
497443
freq_conv_func get_asfreq_func(int fromFreq, int toFreq) {
498444
int fromGroup = get_freq_group(fromFreq);
499445
int toGroup = get_freq_group(toFreq);
@@ -650,9 +596,9 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq) {
650596
case FR_US:
651597
case FR_NS:
652598
if (fromGroup > toGroup) {
653-
return &asfreq_DownsampleWithinDay;
599+
return &downsample_daytime;
654600
} else {
655-
return &asfreq_UpsampleWithinDay;
601+
return &upsample_daytime;
656602
}
657603
default:
658604
return &nofunc;
@@ -662,20 +608,3 @@ freq_conv_func get_asfreq_func(int fromFreq, int toFreq) {
662608
return &nofunc;
663609
}
664610
}
665-
666-
/* ------------------------------------------------------------------
667-
* New pandas API-helper code, to expose to cython
668-
* ------------------------------------------------------------------*/
669-
670-
npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2,
671-
char relation) {
672-
npy_int64 val;
673-
freq_conv_func func;
674-
asfreq_info finfo;
675-
676-
func = get_asfreq_func(freq1, freq2);
677-
678-
get_asfreq_info(freq1, freq2, relation, &finfo);
679-
val = (*func)(period_ordinal, &finfo);
680-
return val;
681-
}

pandas/_libs/src/period_helper.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,9 @@ typedef npy_int64 (*freq_conv_func)(npy_int64, asfreq_info *af_info);
108108
* new pandas API helper functions here
109109
*/
110110

111-
npy_int64 asfreq(npy_int64 period_ordinal, int freq1, int freq2, char relation);
112-
113111
freq_conv_func get_asfreq_func(int fromFreq, int toFreq);
114-
void get_asfreq_info(int fromFreq, int toFreq, char relation,
115-
asfreq_info *af_info);
116112

117113
npy_int64 get_daytime_conversion_factor(int from_index, int to_index);
114+
int max_value(int a, int b);
118115

119116
#endif // PANDAS__LIBS_SRC_PERIOD_HELPER_H_

0 commit comments

Comments
 (0)