33# don't introduce a pandas/pandas.compat import
44# or we get a bootstrapping problem
55from StringIO import StringIO
6+ import numpy as np
7+
8+ _int64_max = np .iinfo (np .int64 ).max
69
710header = """
811cimport numpy as np
@@ -680,7 +683,7 @@ def group_last_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
680683 for i in range(len(counts)):
681684 for j in range(K):
682685 if nobs[i, j] == 0:
683- out[i, j] = nan
686+ out[i, j] = %(nan_val)s
684687 else:
685688 out[i, j] = resx[i, j]
686689"""
@@ -726,7 +729,7 @@ def group_last_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
726729 for i in range(ngroups):
727730 for j in range(K):
728731 if nobs[i, j] == 0:
729- out[i, j] = nan
732+ out[i, j] = %(nan_val)s
730733 else:
731734 out[i, j] = resx[i, j]
732735"""
@@ -773,7 +776,7 @@ def group_nth_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
773776 for i in range(ngroups):
774777 for j in range(K):
775778 if nobs[i, j] == 0:
776- out[i, j] = nan
779+ out[i, j] = %(nan_val)s
777780 else:
778781 out[i, j] = resx[i, j]
779782"""
@@ -819,7 +822,7 @@ def group_nth_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
819822 for i in range(len(counts)):
820823 for j in range(K):
821824 if nobs[i, j] == 0:
822- out[i, j] = nan
825+ out[i, j] = %(nan_val)s
823826 else:
824827 out[i, j] = resx[i, j]
825828"""
@@ -1278,7 +1281,7 @@ def group_min_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
12781281 nobs = np.zeros_like(out)
12791282
12801283 minx = np.empty_like(out)
1281- minx.fill(np.inf )
1284+ minx.fill(%(inf_val)s )
12821285
12831286 if bins[len(bins) - 1] == len(values):
12841287 ngroups = len(bins)
@@ -1319,7 +1322,7 @@ def group_min_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
13191322 for i in range(ngroups):
13201323 for j in range(K):
13211324 if nobs[i, j] == 0:
1322- out[i, j] = nan
1325+ out[i, j] = %(nan_val)s
13231326 else:
13241327 out[i, j] = minx[i, j]
13251328"""
@@ -1344,7 +1347,7 @@ def group_max_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
13441347 nobs = np.zeros_like(out)
13451348
13461349 maxx = np.empty_like(out)
1347- maxx.fill(-np.inf )
1350+ maxx.fill(-%(inf_val)s )
13481351
13491352 N, K = (<object> values).shape
13501353
@@ -1381,7 +1384,7 @@ def group_max_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
13811384 for i in range(len(counts)):
13821385 for j in range(K):
13831386 if nobs[i, j] == 0:
1384- out[i, j] = nan
1387+ out[i, j] = %(nan_val)s
13851388 else:
13861389 out[i, j] = maxx[i, j]
13871390"""
@@ -1402,7 +1405,7 @@ def group_max_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
14021405
14031406 nobs = np.zeros_like(out)
14041407 maxx = np.empty_like(out)
1405- maxx.fill(-np.inf )
1408+ maxx.fill(-%(inf_val)s )
14061409
14071410 if bins[len(bins) - 1] == len(values):
14081411 ngroups = len(bins)
@@ -1443,7 +1446,7 @@ def group_max_bin_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
14431446 for i in range(ngroups):
14441447 for j in range(K):
14451448 if nobs[i, j] == 0:
1446- out[i, j] = nan
1449+ out[i, j] = %(nan_val)s
14471450 else:
14481451 out[i, j] = maxx[i, j]
14491452"""
@@ -1469,7 +1472,7 @@ def group_min_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
14691472 nobs = np.zeros_like(out)
14701473
14711474 minx = np.empty_like(out)
1472- minx.fill(np.inf )
1475+ minx.fill(%(inf_val)s )
14731476
14741477 N, K = (<object> values).shape
14751478
@@ -1506,7 +1509,7 @@ def group_min_%(name)s(ndarray[%(dest_type2)s, ndim=2] out,
15061509 for i in range(len(counts)):
15071510 for j in range(K):
15081511 if nobs[i, j] == 0:
1509- out[i, j] = nan
1512+ out[i, j] = %(nan_val)s
15101513 else:
15111514 out[i, j] = minx[i, j]
15121515"""
@@ -2286,6 +2289,70 @@ def generate_put_template(template, use_ints=True, use_floats=True,
22862289 output .write (func )
22872290 return output .getvalue ()
22882291
2292+ def generate_put_min_max_template (template , use_ints = True , use_floats = True ,
2293+ use_objects = False , use_datelikes = False ):
2294+ floats_list = [
2295+ ('float64' , 'float64_t' , 'nan' , 'np.inf' ),
2296+ ('float32' , 'float32_t' , 'nan' , 'np.inf' ),
2297+ ]
2298+ ints_list = [
2299+ ('int64' , 'int64_t' , 'iNaT' , _int64_max ),
2300+ ]
2301+ date_like_list = [
2302+ ('int64' , 'int64_t' , 'iNaT' , _int64_max ),
2303+ ]
2304+ object_list = [('object' , 'object' , 'nan' , 'np.inf' )]
2305+ function_list = []
2306+ if use_floats :
2307+ function_list .extend (floats_list )
2308+ if use_ints :
2309+ function_list .extend (ints_list )
2310+ if use_objects :
2311+ function_list .extend (object_list )
2312+ if use_datelikes :
2313+ function_list .extend (date_like_list )
2314+
2315+ output = StringIO ()
2316+ for name , dest_type , nan_val , inf_val in function_list :
2317+ func = template % {'name' : name ,
2318+ 'dest_type2' : dest_type ,
2319+ 'nan_val' : nan_val ,
2320+ 'inf_val' : inf_val }
2321+ output .write (func )
2322+ return output .getvalue ()
2323+
2324+ def generate_put_selection_template (template , use_ints = True , use_floats = True ,
2325+ use_objects = False , use_datelikes = False ):
2326+ floats_list = [
2327+ ('float64' , 'float64_t' , 'float64_t' , 'nan' ),
2328+ ('float32' , 'float32_t' , 'float32_t' , 'nan' ),
2329+ ]
2330+ ints_list = [
2331+ ('int64' , 'int64_t' , 'int64_t' , 'iNaT' ),
2332+ ]
2333+ date_like_list = [
2334+ ('int64' , 'int64_t' , 'int64_t' , 'iNaT' ),
2335+ ]
2336+ object_list = [('object' , 'object' , 'object' , 'nan' )]
2337+ function_list = []
2338+ if use_floats :
2339+ function_list .extend (floats_list )
2340+ if use_ints :
2341+ function_list .extend (ints_list )
2342+ if use_objects :
2343+ function_list .extend (object_list )
2344+ if use_datelikes :
2345+ function_list .extend (date_like_list )
2346+
2347+ output = StringIO ()
2348+ for name , c_type , dest_type , nan_val in function_list :
2349+ func = template % {'name' : name ,
2350+ 'c_type' : c_type ,
2351+ 'dest_type2' : dest_type ,
2352+ 'nan_val' : nan_val }
2353+ output .write (func )
2354+ return output .getvalue ()
2355+
22892356def generate_take_template (template , exclude = None ):
22902357 # name, dest, ctypein, ctypeout, preval, postval, cancopy
22912358 function_list = [
@@ -2347,24 +2414,27 @@ def generate_from_template(template, exclude=None):
23472414 return output .getvalue ()
23482415
23492416put_2d = [diff_2d_template ]
2350- groupbys = [group_last_template ,
2351- group_last_bin_template ,
2352- group_nth_template ,
2353- group_nth_bin_template ,
2354- group_add_template ,
2417+
2418+ groupbys = [group_add_template ,
23552419 group_add_bin_template ,
23562420 group_prod_template ,
23572421 group_prod_bin_template ,
23582422 group_var_template ,
23592423 group_var_bin_template ,
23602424 group_mean_template ,
23612425 group_mean_bin_template ,
2362- group_min_template ,
2363- group_min_bin_template ,
2364- group_max_template ,
2365- group_max_bin_template ,
23662426 group_ohlc_template ]
23672427
2428+ groupby_selection = [group_last_template ,
2429+ group_last_bin_template ,
2430+ group_nth_template ,
2431+ group_nth_bin_template ]
2432+
2433+ groupby_min_max = [group_min_template ,
2434+ group_min_bin_template ,
2435+ group_max_template ,
2436+ group_max_bin_template ]
2437+
23682438groupby_count = [group_count_template , group_count_bin_template ]
23692439
23702440templates_1d = [map_indices_template ,
@@ -2407,9 +2477,18 @@ def generate_take_cython_file(path='generated.pyx'):
24072477 for template in groupbys :
24082478 print (generate_put_template (template , use_ints = False ), file = f )
24092479
2480+ for template in groupby_selection :
2481+ print (generate_put_selection_template (template , use_ints = True ),
2482+ file = f )
2483+
2484+ for template in groupby_min_max :
2485+ print (generate_put_min_max_template (template , use_ints = True ),
2486+ file = f )
2487+
24102488 for template in groupby_count :
2411- print (generate_put_template (template , use_ints = False ,
2412- use_datelikes = True , use_objects = True ),
2489+ print (generate_put_selection_template (template , use_ints = True ,
2490+ use_datelikes = True ,
2491+ use_objects = True ),
24132492 file = f )
24142493
24152494 # for template in templates_1d_datetime:
0 commit comments