Skip to content

Commit 824cb10

Browse files
committed
ENH: add internals.ComplexBlock
1 parent a351e94 commit 824cb10

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

pandas/core/internals.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ def should_store(self, value):
243243
# unnecessarily
244244
return issubclass(value.dtype.type, np.floating)
245245

246+
class ComplexBlock(Block):
247+
_can_hold_na = True
248+
249+
def should_store(self, value):
250+
return issubclass(value.dtype.type, np.complexfloating)
251+
246252
class IntBlock(Block):
247253
_can_hold_na = False
248254

@@ -260,7 +266,8 @@ class ObjectBlock(Block):
260266

261267
def should_store(self, value):
262268
return not issubclass(value.dtype.type,
263-
(np.integer, np.floating, np.bool_))
269+
(np.integer, np.floating, np.complexfloating,
270+
np.bool_))
264271

265272
class DatetimeBlock(IntBlock):
266273
_can_hold_na = True
@@ -272,6 +279,8 @@ def make_block(values, items, ref_items, do_integrity_check=False):
272279

273280
if issubclass(vtype, np.floating):
274281
klass = FloatBlock
282+
elif issubclass(vtype, np.complexfloating):
283+
klass = ComplexBlock
275284
elif issubclass(vtype, np.datetime64):
276285
klass = DatetimeBlock
277286
elif issubclass(vtype, np.integer):
@@ -416,7 +425,7 @@ def is_consolidated(self):
416425

417426
def get_numeric_data(self, copy=False):
418427
num_blocks = [b for b in self.blocks
419-
if isinstance(b, (IntBlock, FloatBlock))]
428+
if isinstance(b, (IntBlock, FloatBlock, ComplexBlock))]
420429

421430
indexer = np.sort(np.concatenate([b.ref_locs for b in num_blocks]))
422431
new_items = self.items.take(indexer)
@@ -1094,19 +1103,22 @@ def _interleaved_dtype(blocks):
10941103
have_bool = counts[BoolBlock] > 0
10951104
have_object = counts[ObjectBlock] > 0
10961105
have_float = counts[FloatBlock] > 0
1106+
have_complex = counts[ComplexBlock] > 0
10971107
have_dt64 = counts[DatetimeBlock] > 0
1098-
have_numeric = have_float or have_int
1108+
have_numeric = have_float or have_complex or have_int
10991109

11001110
if have_object:
11011111
return np.object_
11021112
elif have_bool and have_numeric:
11031113
return np.object_
11041114
elif have_bool:
11051115
return np.bool_
1106-
elif have_int and not have_float:
1116+
elif have_int and not have_float and not have_complex:
11071117
return np.int64
1108-
elif have_dt64 and not have_float:
1118+
elif have_dt64 and not have_float and not have_complex:
11091119
return np.datetime64
1120+
elif have_complex:
1121+
return np.complex64
11101122
else:
11111123
return np.float64
11121124

pandas/src/tseries.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ cdef double INF = <double> np.inf
156156
cdef double NEGINF = -INF
157157

158158
cpdef checknull(object val):
159-
if util.is_float_object(val):
159+
if util.is_float_object(val) or util.is_complex_object(val):
160160
return val != val or val == INF or val == NEGINF
161161
elif util.is_datetime64_object(val):
162162
return val.view('i8') == NaT

pandas/tests/test_internals.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ def assert_block_equal(left, right):
1919
def get_float_mat(n, k):
2020
return np.repeat(np.atleast_2d(np.arange(k, dtype=float)), n, axis=0)
2121

22-
TEST_COLS = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
22+
TEST_COLS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
2323
N = 10
2424

2525
def get_float_ex(cols=['a', 'c', 'e']):
2626
floats = get_float_mat(N, 3).T
2727
return make_block(floats, cols, TEST_COLS)
2828

29+
def get_complex_ex(cols=['h']):
30+
complexes = (get_float_mat(N, 1).T * 1j).astype(np.complex64)
31+
return make_block(complexes, cols, TEST_COLS)
32+
2933
def get_obj_ex(cols=['b', 'd']):
3034
mat = np.empty((N, 2), dtype=object)
3135
mat[:, 0] = 'foo'
@@ -44,6 +48,7 @@ class TestBlock(unittest.TestCase):
4448

4549
def setUp(self):
4650
self.fblock = get_float_ex()
51+
self.cblock = get_complex_ex()
4752
self.oblock = get_obj_ex()
4853
self.bool_block = get_bool_ex()
4954
self.int_block = get_int_ex()
@@ -60,6 +65,7 @@ def _check(blk):
6065
assert_block_equal(blk, unpickled)
6166

6267
_check(self.fblock)
68+
_check(self.cblock)
6369
_check(self.oblock)
6470
_check(self.bool_block)
6571

@@ -175,7 +181,8 @@ def setUp(self):
175181
self.blocks = [get_float_ex(),
176182
get_obj_ex(),
177183
get_bool_ex(),
178-
get_int_ex()]
184+
get_int_ex(),
185+
get_complex_ex()]
179186
self.mgr = BlockManager.from_blocks(self.blocks, np.arange(N))
180187

181188
def test_constructor_corner(self):
@@ -198,13 +205,13 @@ def test_is_indexed_like(self):
198205
self.assert_(not self.mgr._is_indexed_like(mgr2))
199206

200207
def test_block_id_vector_item_dtypes(self):
201-
expected = [0, 1, 0, 1, 0, 2, 3]
208+
expected = [0, 1, 0, 1, 0, 2, 3, 4]
202209
result = self.mgr.block_id_vector
203210
assert_almost_equal(expected, result)
204211

205212
result = self.mgr.item_dtypes
206213
expected = ['float64', 'object', 'float64', 'object', 'float64',
207-
'bool', 'int64']
214+
'bool', 'int64', 'complex64']
208215
self.assert_(np.array_equal(result, expected))
209216

210217
def test_union_block_items(self):
@@ -298,6 +305,7 @@ def test_consolidate_ordering_issues(self):
298305
self.mgr.set('d', randn(N))
299306
self.mgr.set('b', randn(N))
300307
self.mgr.set('g', randn(N))
308+
self.mgr.set('h', randn(N))
301309

302310
cons = self.mgr.consolidate()
303311
self.assertEquals(cons.nblocks, 1)

0 commit comments

Comments
 (0)