Skip to content

Commit cc21b3f

Browse files
tkfwesm
authored andcommitted
ENH: add internals.ComplexBlock
1 parent e005cbe commit cc21b3f

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

pandas/core/internals.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ def should_store(self, value):
250250
# unnecessarily
251251
return issubclass(value.dtype.type, np.floating)
252252

253+
class ComplexBlock(Block):
254+
_can_hold_na = True
255+
256+
def should_store(self, value):
257+
return issubclass(value.dtype.type, np.complexfloating)
258+
253259
class IntBlock(Block):
254260
_can_hold_na = False
255261

@@ -267,7 +273,8 @@ class ObjectBlock(Block):
267273

268274
def should_store(self, value):
269275
return not issubclass(value.dtype.type,
270-
(np.integer, np.floating, np.bool_))
276+
(np.integer, np.floating, np.complexfloating,
277+
np.bool_))
271278

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

280287
if issubclass(vtype, np.floating):
281288
klass = FloatBlock
289+
elif issubclass(vtype, np.complexfloating):
290+
klass = ComplexBlock
282291
elif issubclass(vtype, np.datetime64):
283292
klass = DatetimeBlock
284293
elif issubclass(vtype, np.integer):
@@ -423,7 +432,7 @@ def is_consolidated(self):
423432

424433
def get_numeric_data(self, copy=False):
425434
num_blocks = [b for b in self.blocks
426-
if isinstance(b, (IntBlock, FloatBlock))]
435+
if isinstance(b, (IntBlock, FloatBlock, ComplexBlock))]
427436

428437
indexer = np.sort(np.concatenate([b.ref_locs for b in num_blocks]))
429438
new_items = self.items.take(indexer)
@@ -1103,19 +1112,22 @@ def _interleaved_dtype(blocks):
11031112
have_bool = counts[BoolBlock] > 0
11041113
have_object = counts[ObjectBlock] > 0
11051114
have_float = counts[FloatBlock] > 0
1115+
have_complex = counts[ComplexBlock] > 0
11061116
have_dt64 = counts[DatetimeBlock] > 0
1107-
have_numeric = have_float or have_int
1117+
have_numeric = have_float or have_complex or have_int
11081118

11091119
if have_object:
11101120
return np.object_
11111121
elif have_bool and have_numeric:
11121122
return np.object_
11131123
elif have_bool:
11141124
return np.bool_
1115-
elif have_int and not have_float:
1125+
elif have_int and not have_float and not have_complex:
11161126
return np.int64
1117-
elif have_dt64 and not have_float:
1127+
elif have_dt64 and not have_float and not have_complex:
11181128
return np.datetime64
1129+
elif have_complex:
1130+
return np.complex64
11191131
else:
11201132
return np.float64
11211133

pandas/src/tseries.pyx

+1-1
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

+12-4
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)