Skip to content

Commit 09553cc

Browse files
committed
BUG: can print Series/DataFrame with ndarray cell elements, GH #490
1 parent ff73455 commit 09553cc

File tree

5 files changed

+56
-14
lines changed

5 files changed

+56
-14
lines changed

pandas/core/series.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from pandas.core.indexing import _SeriesIndexer, _maybe_droplevels
2222
from pandas.util import py3compat
2323
from pandas.util.terminal import get_terminal_size
24-
import pandas.core.common as common
24+
import pandas.core.common as com
2525
import pandas.core.datetools as datetools
2626
import pandas.core.nanops as nanops
2727
import pandas._tseries as lib
@@ -430,7 +430,7 @@ def __setslice__(self, i, j, value):
430430
def __repr__(self):
431431
"""Clean string representation of a Series"""
432432
width, height = get_terminal_size()
433-
max_rows = height if common._max_rows == 0 else common._max_rows
433+
max_rows = height if com._max_rows == 0 else com._max_rows
434434
if len(self.index) > max_rows:
435435
result = self._tidy_repr(min(30, max_rows - 4))
436436
elif len(self.index) > 0:
@@ -491,14 +491,16 @@ def _get_repr(self, name=False, print_header=False, length=True,
491491
padSpace = min(maxlen, 60)
492492

493493
if float_format is None:
494-
float_format = common._float_format
494+
float_format = com._float_format
495495

496496
def _format(k, v):
497-
if isnull(v):
497+
# GH #490
498+
if not isinstance(v, np.ndarray) and isnull(v):
498499
v = na_rep
499-
if isinstance(v, (float, np.floating)):
500+
if com.is_float(v):
500501
v = float_format(v)
501-
return '%s %s' % (str(k).ljust(padSpace), v)
502+
return '%s %s' % (str(k).ljust(padSpace),
503+
str(v).replace('\n', ' '))
502504

503505
it = [_format(idx, v) for idx, v in izip(string_index, vals)]
504506

@@ -1398,7 +1400,7 @@ def map(self, arg):
13981400
indexer = lib.merge_indexer_object(self.values.astype(object),
13991401
arg.index.indexMap)
14001402

1401-
new_values = common.take_1d(np.asarray(arg), indexer)
1403+
new_values = com.take_1d(np.asarray(arg), indexer)
14021404
return Series(new_values, index=self.index, name=self.name)
14031405
else:
14041406
mapped = lib.map_infer(self.values, arg)
@@ -1452,7 +1454,7 @@ def align(self, other, join='outer', copy=True):
14521454

14531455
def _align_series(series, indexer):
14541456
if indexer is not None:
1455-
new_values = common.take_1d(series.values, indexer)
1457+
new_values = com.take_1d(series.values, indexer)
14561458
else:
14571459
if copy:
14581460
new_values = series.values.copy()
@@ -1499,7 +1501,7 @@ def reindex(self, index=None, method=None, copy=True):
14991501
return Series(nan, index=index, name=self.name)
15001502

15011503
new_index, fill_vec = self.index.reindex(index, method=method)
1502-
new_values = common.take_1d(self.values, fill_vec)
1504+
new_values = com.take_1d(self.values, fill_vec)
15031505
return Series(new_values, index=new_index, name=self.name)
15041506

15051507
def reindex_like(self, other, method=None):

pandas/src/sandbox.pyx

+28-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
from numpy cimport *
1+
from numpy cimport ndarray, int64_t
2+
cimport numpy as cnp
23
import numpy as np
34

4-
import_array()
5+
cimport cpython
6+
7+
cnp.import_array()
58

69
cdef class SeriesIterator:
710

@@ -25,3 +28,26 @@ def bench_dict():
2528

2629
for i in range(1000000):
2730
d[i] = i
31+
32+
from cpython cimport PyObject
33+
34+
cdef extern from "numpy/arrayobject.h":
35+
bint PyArray_Check(PyObject*)
36+
37+
cimport cython
38+
39+
@cython.boundscheck(False)
40+
@cython.wraparound(False)
41+
def bench_typecheck1(ndarray[object] arr):
42+
cdef Py_ssize_t i, n
43+
n = cnp.PyArray_SIZE(arr)
44+
for i in range(n):
45+
cpython.PyFloat_Check(arr[i])
46+
47+
def bench_typecheck2(ndarray[object] arr):
48+
cdef Py_ssize_t i, n
49+
cdef PyObject** buf = <PyObject**> arr.data
50+
n = cnp.PyArray_SIZE(arr)
51+
for i in range(n):
52+
PyArray_Check(buf[i])
53+

pandas/src/tseries.pyx

+4-2
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,13 @@ cdef double INF = <double> np.inf
261261
cdef double NEGINF = -INF
262262

263263
cdef inline _checknull(object val):
264-
return val is None or val != val
264+
return not np.PyArray_Check(val) and (val is None or val != val)
265265

266266
cpdef checknull(object val):
267-
if isinstance(val, (float, np.floating)):
267+
if util.is_float_object(val):
268268
return val != val or val == INF or val == NEGINF
269+
elif is_array(val):
270+
return False
269271
else:
270272
return _checknull(val)
271273

pandas/tests/test_frame.py

+10
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,16 @@ def test_repr(self):
14991499
com.set_printoptions(precision=3, column_space=10)
15001500
repr(self.frame)
15011501

1502+
def test_repr_embedded_ndarray(self):
1503+
arr = np.empty(10, dtype=[('err', object)])
1504+
for i in range(len(arr)):
1505+
arr['err'][i] = np.random.randn(i)
1506+
1507+
df = DataFrame(arr)
1508+
repr(df['err'])
1509+
repr(df)
1510+
df.to_string()
1511+
15021512
def test_eng_float_formatter(self):
15031513
self.frame.ix[5] = 0
15041514

setup.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,12 @@ def srcpath(name=None, suffix='.pyx', subdir='src'):
290290
if suffix == '.pyx':
291291
tseries_depends = [srcpath(f, suffix='.pyx')
292292
for f in tseries_depends]
293-
tseries_depends.append('util.pxd')
293+
tseries_depends.append('pandas/src/util.pxd')
294294
else:
295295
tseries_depends = []
296296

297+
print tseries_depends
298+
297299
tseries_ext = Extension('pandas._tseries',
298300
depends=tseries_depends + ['pandas/src/numpy_helper.h'],
299301
sources=[srcpath('tseries', suffix=suffix)],

0 commit comments

Comments
 (0)