Commit 8328777b authored by Dr.李's avatar Dr.李

remove the dependency of cython

parent 3697dcb5
...@@ -11,11 +11,40 @@ import numba as nb ...@@ -11,11 +11,40 @@ import numba as nb
def groupby(groups): def groupby(groups):
a = np.arange(groups.shape[0])
order_group_idx = groups.argsort() order_group_idx = groups.argsort()
counts = np.bincount(groups) counts = np.bincount(groups)
ret = np.split(a[order_group_idx], np.cumsum(counts)[:-1]) nonzero_idx = counts.nonzero()[0]
return ret
start = 0
res = []
for i in nonzero_idx:
num_g = counts[i]
res.append(order_group_idx[start:start+num_g])
start += num_g
return res
@nb.njit(nogil=True, cache=True)
def group_mapping(groups):
length = groups.shape[0]
order = groups.argsort()
res = np.zeros(length, dtype=order.dtype)
start = 0
res[order[0]] = start
previous = groups[order[0]]
for i in range(1, length):
curr_idx = order[i]
curr_val = groups[curr_idx]
if curr_val != previous:
start += 1
res[curr_idx] = start
else:
res[curr_idx] = start
previous = curr_val
return res
@nb.njit(nogil=True, cache=True) @nb.njit(nogil=True, cache=True)
......
...@@ -57,7 +57,7 @@ def benchmark_simple_settle_with_group(n_samples: int, n_portfolios: int, n_loop ...@@ -57,7 +57,7 @@ def benchmark_simple_settle_with_group(n_samples: int, n_portfolios: int, n_loop
ret_series.shape = -1, 1 ret_series.shape = -1, 1
for _ in range(n_loops): for _ in range(n_loops):
ret_mat = weights * ret_series ret_mat = weights * ret_series
exp_ret = pd.DataFrame(ret_mat).groupby(groups, sort=False).sum().values exp_ret = pd.DataFrame(ret_mat).groupby(groups).sum().values
benchmark_model_time = dt.datetime.now() - start benchmark_model_time = dt.datetime.now() - start
np.testing.assert_array_almost_equal(calc_ret, exp_ret) np.testing.assert_array_almost_equal(calc_ret, exp_ret)
......
...@@ -6,7 +6,7 @@ Created on 2017-4-25 ...@@ -6,7 +6,7 @@ Created on 2017-4-25
""" """
import numpy as np import numpy as np
from alphamind.groupby import group_mapping from alphamind.aggregate import group_mapping
from alphamind.aggregate import transform from alphamind.aggregate import transform
from alphamind.aggregate import simple_mean from alphamind.aggregate import simple_mean
from alphamind.aggregate import simple_std from alphamind.aggregate import simple_std
......
...@@ -7,7 +7,7 @@ Created on 2017-4-25 ...@@ -7,7 +7,7 @@ Created on 2017-4-25
import numpy as np import numpy as np
import numba as nb import numba as nb
from alphamind.groupby import group_mapping from alphamind.aggregate import group_mapping
from alphamind.aggregate import transform from alphamind.aggregate import transform
from alphamind.aggregate import simple_mean from alphamind.aggregate import simple_mean
from alphamind.aggregate import simple_std from alphamind.aggregate import simple_std
......
# -*- coding: utf-8 -*-
# distutils: language = c++
"""
Created on 2017-4-26
@author: cheng.li
"""
import numpy as np
from numpy import zeros
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.initializedcheck(False)
cpdef np.ndarray[long, ndim=1] group_mapping(long[:] groups):
cdef size_t length = groups.shape[0]
cdef np.ndarray[long, ndim=1] res= zeros(length, dtype=long)
cdef dict current_hold = {}
cdef long curr_tag
cdef long running_tag = -1
cdef size_t i
for i in range(length):
curr_tag = groups[i]
try:
res[i] = current_hold[curr_tag]
except KeyError:
running_tag += 1
res[i] = running_tag
current_hold[curr_tag] = running_tag
return res
...@@ -6,7 +6,7 @@ Created on 2017-4-28 ...@@ -6,7 +6,7 @@ Created on 2017-4-28
""" """
import numpy as np import numpy as np
from alphamind.groupby import group_mapping from alphamind.aggregate import group_mapping
from alphamind.aggregate import aggregate from alphamind.aggregate import aggregate
from alphamind.aggregate import simple_sum from alphamind.aggregate import simple_sum
......
...@@ -48,7 +48,7 @@ class TestSimpleSettle(unittest.TestCase): ...@@ -48,7 +48,7 @@ class TestSimpleSettle(unittest.TestCase):
ret_series.shape = -1, 1 ret_series.shape = -1, 1
ret_mat = weights * ret_series ret_mat = weights * ret_series
expected_ret = pd.DataFrame(ret_mat).groupby(groups, sort=False).sum().values expected_ret = pd.DataFrame(ret_mat).groupby(groups).sum().values
np.testing.assert_array_almost_equal(calc_ret, expected_ret) np.testing.assert_array_almost_equal(calc_ret, expected_ret)
...@@ -57,7 +57,7 @@ class TestSimpleSettle(unittest.TestCase): ...@@ -57,7 +57,7 @@ class TestSimpleSettle(unittest.TestCase):
calc_ret = simple_settle(weights, ret_series, groups) calc_ret = simple_settle(weights, ret_series, groups)
ret_mat = weights * ret_series ret_mat = weights * ret_series
expected_ret = pd.DataFrame(ret_mat).groupby(groups, sort=False).sum().values expected_ret = pd.DataFrame(ret_mat).groupby(groups).sum().values
np.testing.assert_array_almost_equal(calc_ret, expected_ret) np.testing.assert_array_almost_equal(calc_ret, expected_ret)
......
cython >= 0.25.2 cython >= 0.25.2
numpy >= 1.12.1 numpy >= 1.12.1
numba >= 0.30.0
scikit-learn >= 0.18.1 scikit-learn >= 0.18.1
scipy >= 0.19.0 scipy >= 0.19.0
pandas >= 0.19.2 pandas >= 0.19.2
\ No newline at end of file
...@@ -5,63 +5,11 @@ Created on 2017-4-25 ...@@ -5,63 +5,11 @@ Created on 2017-4-25
@author: cheng.li @author: cheng.li
""" """
import platform
import sys
from setuptools import setup from setuptools import setup
from setuptools import find_packages from setuptools import find_packages
from distutils.extension import Extension
import numpy as np
import Cython
from Cython.Build import cythonize
Cython.Compiler.Options.annotate = True
VERSION = "0.1.0" VERSION = "0.1.0"
if "--line_trace" in sys.argv:
line_trace = True
print("Build with line trace enabled ...")
sys.argv.remove("--line_trace")
else:
line_trace = False
ext_modules = ['alphamind/groupby.pyx']
def generate_extensions(ext_modules, line_trace=False):
extensions = []
if line_trace:
print("define cython trace to True ...")
define_macros = [('CYTHON_TRACE', 1), ('CYTHON_TRACE_NOGIL', 1)]
else:
define_macros = []
if platform.system() != "Windows":
extra_compile_args = ['-O3', '-std=c++11']
else:
extra_compile_args = ['/Ox']
for pyxfile in ext_modules:
ext = Extension(name='.'.join(pyxfile.split('/'))[:-4],
sources=[pyxfile],
define_macros=define_macros,
extra_compile_args=extra_compile_args)
extensions.append(ext)
return extensions
if platform.system() != "Windows":
import multiprocessing
n_cpu = multiprocessing.cpu_count()
else:
n_cpu = 0
ext_modules_settings = cythonize(generate_extensions(ext_modules, line_trace),
compiler_directives={'embedsignature': True, 'linetrace': line_trace},
nthreads=n_cpu)
setup( setup(
name='Alpha-Mind', name='Alpha-Mind',
...@@ -71,7 +19,5 @@ setup( ...@@ -71,7 +19,5 @@ setup(
license='', license='',
author='wegamekinglc', author='wegamekinglc',
author_email='', author_email='',
ext_modules=ext_modules_settings,
include_dirs=[np.get_include()],
description='' description=''
) )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment