@@ -83,7 +83,6 @@ typedef struct __PdBlockContext {
8383 int ncols ;
8484 int transpose ;
8585
86- int * cindices ; // frame column -> block column map
8786 NpyArrContext * * npyCtxts ; // NpyArrContext for each column
8887} PdBlockContext ;
8988
@@ -294,7 +293,12 @@ static int is_simple_frame(PyObject *obj) {
294293 if (!mgr ) {
295294 return 0 ;
296295 }
297- int ret = (get_attr_length (mgr , "blocks" ) <= 1 );
296+ int ret ;
297+ if (PyObject_HasAttrString (mgr , "blocks" )) {
298+ ret = (get_attr_length (mgr , "blocks" ) <= 1 );
299+ } else {
300+ ret = 0 ;
301+ }
298302
299303 Py_DECREF (mgr );
300304 return ret ;
@@ -656,16 +660,10 @@ void PdBlockPassThru_iterBegin(JSOBJ Py_UNUSED(obj), JSONTypeContext *tc) {
656660}
657661
658662void PdBlock_iterBegin (JSOBJ _obj , JSONTypeContext * tc ) {
659- PyObject * obj , * blocks , * block , * values , * tmp ;
660- PyArrayObject * locs ;
663+ PyObject * obj , * values , * arrays , * array ;
661664 PdBlockContext * blkCtxt ;
662665 NpyArrContext * npyarr ;
663666 Py_ssize_t i ;
664- NpyIter * iter ;
665- NpyIter_IterNextFunc * iternext ;
666- npy_int64 * * dataptr ;
667- npy_int64 colIdx ;
668- npy_intp idx ;
669667
670668 obj = (PyObject * )_obj ;
671669
@@ -687,7 +685,6 @@ void PdBlock_iterBegin(JSOBJ _obj, JSONTypeContext *tc) {
687685
688686 if (blkCtxt -> ncols == 0 ) {
689687 blkCtxt -> npyCtxts = NULL ;
690- blkCtxt -> cindices = NULL ;
691688
692689 GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
693690 return ;
@@ -701,104 +698,45 @@ void PdBlock_iterBegin(JSOBJ _obj, JSONTypeContext *tc) {
701698 return ;
702699 }
703700
704- blkCtxt -> cindices = PyObject_Malloc (sizeof (int ) * blkCtxt -> ncols );
705- if (!blkCtxt -> cindices ) {
706- PyErr_NoMemory ();
707- GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
708- return ;
709- }
710-
711- blocks = get_sub_attr (obj , "_mgr" , "blocks" );
712- if (!blocks ) {
701+ arrays = get_sub_attr (obj , "_mgr" , "column_arrays" );
702+ if (!arrays ) {
713703 GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
714704 return ;
715- } else if (!PyTuple_Check (blocks )) {
716- PyErr_SetString (PyExc_TypeError , "blocks must be a tuple!" );
717- goto BLKRET ;
718705 }
719706
720- // force transpose so each NpyArrContext strides down its column
721- GET_TC (tc )-> transpose = 1 ;
722-
723- for (i = 0 ; i < PyObject_Length (blocks ); i ++ ) {
724- block = PyTuple_GET_ITEM (blocks , i );
725- if (!block ) {
707+ for (i = 0 ; i < PyObject_Length (arrays ); i ++ ) {
708+ array = PyList_GET_ITEM (arrays , i );
709+ if (!array ) {
726710 GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
727- goto BLKRET ;
711+ goto ARR_RET ;
728712 }
729713
730- tmp = PyObject_CallMethod (block , "get_block_values_for_json" , NULL );
731- if (!tmp ) {
714+ // ensure we have a numpy array (i.e. np.asarray)
715+ values = PyObject_CallMethod (array , "__array__" , NULL );
716+ if ((!values ) || (!PyArray_CheckExact (values ))) {
717+ // Didn't get a numpy array
732718 ((JSONObjectEncoder * )tc -> encoder )-> errorMsg = "" ;
733719 GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
734- goto BLKRET ;
735- }
736-
737- values = PyArray_Transpose ((PyArrayObject * )tmp , NULL );
738- Py_DECREF (tmp );
739- if (!values ) {
740- GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
741- goto BLKRET ;
742- }
743-
744- locs = (PyArrayObject * )get_sub_attr (block , "mgr_locs" , "as_array" );
745- if (!locs ) {
746- Py_DECREF (values );
747- GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
748- goto BLKRET ;
720+ goto ARR_RET ;
749721 }
750722
751- iter = NpyIter_New (locs , NPY_ITER_READONLY , NPY_KEEPORDER ,
752- NPY_NO_CASTING , NULL );
753- if (!iter ) {
754- Py_DECREF (values );
755- Py_DECREF (locs );
756- GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
757- goto BLKRET ;
758- }
759- iternext = NpyIter_GetIterNext (iter , NULL );
760- if (!iternext ) {
761- NpyIter_Deallocate (iter );
762- Py_DECREF (values );
763- Py_DECREF (locs );
764- GET_TC (tc )-> iterNext = NpyArr_iterNextNone ;
765- goto BLKRET ;
766- }
767- dataptr = (npy_int64 * * )NpyIter_GetDataPtrArray (iter );
768- do {
769- colIdx = * * dataptr ;
770- idx = NpyIter_GetIterIndex (iter );
723+ GET_TC (tc )-> newObj = values ;
771724
772- blkCtxt -> cindices [colIdx ] = idx ;
725+ // init a dedicated context for this column
726+ NpyArr_iterBegin (obj , tc );
727+ npyarr = GET_TC (tc )-> npyarr ;
773728
774- // Reference freed in Pdblock_iterend
775- Py_INCREF (values );
776- GET_TC (tc )-> newObj = values ;
777-
778- // init a dedicated context for this column
779- NpyArr_iterBegin (obj , tc );
780- npyarr = GET_TC (tc )-> npyarr ;
781-
782- // set the dataptr to our desired column and initialise
783- if (npyarr != NULL ) {
784- npyarr -> dataptr += npyarr -> stride * idx ;
785- NpyArr_iterNext (obj , tc );
786- }
787- GET_TC (tc )-> itemValue = NULL ;
788- ((PyObjectEncoder * )tc -> encoder )-> npyCtxtPassthru = NULL ;
789-
790- blkCtxt -> npyCtxts [colIdx ] = npyarr ;
791- GET_TC (tc )-> newObj = NULL ;
792- } while (iternext (iter ));
729+ GET_TC (tc )-> itemValue = NULL ;
730+ ((PyObjectEncoder * )tc -> encoder )-> npyCtxtPassthru = NULL ;
793731
794- NpyIter_Deallocate (iter );
795- Py_DECREF (values );
796- Py_DECREF (locs );
732+ blkCtxt -> npyCtxts [i ] = npyarr ;
733+ GET_TC (tc )-> newObj = NULL ;
797734 }
798735 GET_TC (tc )-> npyarr = blkCtxt -> npyCtxts [0 ];
736+ goto ARR_RET ;
799737
800- BLKRET :
801- Py_DECREF (blocks );
738+ ARR_RET :
739+ Py_DECREF (arrays );
802740}
803741
804742void PdBlock_iterEnd (JSOBJ obj , JSONTypeContext * tc ) {
@@ -830,9 +768,6 @@ void PdBlock_iterEnd(JSOBJ obj, JSONTypeContext *tc) {
830768 if (blkCtxt -> npyCtxts ) {
831769 PyObject_Free (blkCtxt -> npyCtxts );
832770 }
833- if (blkCtxt -> cindices ) {
834- PyObject_Free (blkCtxt -> cindices );
835- }
836771 PyObject_Free (blkCtxt );
837772 }
838773}
0 commit comments