Skip to content

Commit

Permalink
BUG: avoid unnecessary copies when passed dtype matches DataFrame/nda…
Browse files Browse the repository at this point in the history
…rray in DataFrame constructor close #1572
  • Loading branch information
wesm committed Jul 11, 2012
1 parent 9a8ad65 commit 3ce416b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
14 changes: 8 additions & 6 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,9 @@ def _init_mgr(self, mgr, index, columns, dtype=None, copy=False):
if copy and dtype is None:
mgr = mgr.copy()
elif dtype is not None:
# no choice but to copy
mgr = mgr.astype(dtype)
# avoid copy if we can
if len(mgr.blocks) > 1 or mgr.blocks[0].values.dtype != dtype:
mgr = mgr.astype(dtype)
return mgr

def _init_dict(self, data, index, columns, dtype=None):
Expand Down Expand Up @@ -482,10 +483,11 @@ def _init_ndarray(self, values, index, columns, dtype=None,
values = _prep_ndarray(values, copy=copy)

if dtype is not None:
try:
values = values.astype(dtype)
except Exception:
raise ValueError('failed to cast to %s' % dtype)
if values.dtype != dtype:
try:
values = values.astype(dtype)
except Exception:
raise ValueError('failed to cast to %s' % dtype)

N, K = values.shape

Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,16 @@ def test_constructor_cast_failure(self):
foo = DataFrame({'a': ['a', 'b', 'c']}, dtype=np.float64)
self.assert_(foo['a'].dtype == object)

def test_constructor_dtype_nocast_view(self):
df = DataFrame([[1, 2]])
should_be_view = DataFrame(df, dtype=df[0].dtype)
should_be_view[0][0] = 99
self.assertEqual(df.values[0, 0], 99)

should_be_view = DataFrame(df.values, dtype=df[0].dtype)
should_be_view[0][0] = 97
self.assertEqual(df.values[0, 0], 97)

def test_constructor_rec(self):
rec = self.frame.to_records(index=False)

Expand Down
9 changes: 9 additions & 0 deletions pandas/tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,15 @@ def test_constructor_pass_none(self):
def test_constructor_cast(self):
self.assertRaises(ValueError, Series, ['a', 'b', 'c'], dtype=float)

def test_constructor_dtype_nocast(self):
# #1572
s = Series([1, 2, 3])

s2 = Series(s, dtype=np.int64)

s2[1] = 5
self.assertEquals(s[1], 5)

def test_constructor_dict(self):
d = {'a' : 0., 'b' : 1., 'c' : 2.}
result = Series(d, index=['b', 'c', 'd', 'a'])
Expand Down

0 comments on commit 3ce416b

Please sign in to comment.