Skip to content

Commit 31850d6

Browse files
committed
Merge branch 'master' into widepanel-refactor
* master: BUG: fixed GH #56 BUG: in as_matrix with subset of columns with single-block always copy data when inserting into DataFrame. failing reverse op dtype=object unit test
2 parents 8651298 + 93d4461 commit 31850d6

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-2
lines changed

pandas/core/frame.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -786,11 +786,14 @@ def _insert_item(self, key, value):
786786
Series/TimeSeries will be conformed to the DataFrame's index to
787787
ensure homogeneity.
788788
"""
789+
# Need to make sure new columns (which go into the BlockManager as new
790+
# blocks) are always copied
791+
789792
if hasattr(value, '__iter__'):
790793
if isinstance(value, Series):
791794
if value.index.equals(self.index):
792-
# no need to copy
793-
value = value.values
795+
# copy the values
796+
value = value.values.copy()
794797
else:
795798
value = value.reindex(self.index).values
796799
else:
@@ -800,6 +803,8 @@ def _insert_item(self, key, value):
800803
value = np.array(value)
801804
if value.dtype.type == np.str_:
802805
value = np.array(value, dtype=object)
806+
else:
807+
value = value.copy()
803808
else:
804809
value = np.repeat(value, len(self.index))
805810

pandas/core/internals.py

+2
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ def as_matrix(self, items=None):
373373
if items is None or blk.items.equals(items):
374374
# if not, then just call interleave per below
375375
mat = blk.values
376+
else:
377+
mat = self.reindex_columns(columns).as_matrix()
376378
else:
377379
if items is None:
378380
mat = self._interleave(self.items)

pandas/core/series.py

+12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ def _arith_method(op, name):
3535
'__sub__' : '__rsub__',
3636
'__div__' : '__rdiv__',
3737
'__mul__' : '__rmul__',
38+
'__radd__' : '__add__',
39+
'__rsub__' : '__sub__',
40+
'__rdiv__' : '__div__',
41+
'__rmul__' : '__mul__',
3842
}
3943
def wrapper(self, other):
4044
from pandas.core.frame import DataFrame
@@ -445,6 +449,14 @@ def copy(self):
445449
__div__ = _arith_method(operator.div, '__div__')
446450
__truediv__ = _arith_method(operator.truediv, '__truediv__')
447451
__pow__ = _arith_method(operator.pow, '__pow__')
452+
__truediv__ = _arith_method(operator.truediv, '__truediv__')
453+
454+
__radd__ = _arith_method(operator.add, '__add__')
455+
__rmul__ = _arith_method(operator.mul, '__mul__')
456+
__rsub__ = _arith_method(lambda x, y: y - x, '__sub__')
457+
__rdiv__ = _arith_method(lambda x, y: y / x, '__div__')
458+
__rtruediv__ = _arith_method(lambda x, y: y / x, '__truediv__')
459+
__rpow__ = _arith_method(lambda x, y: y ** x, '__pow__')
448460

449461
# Inplace operators
450462
__iadd__ = __add__

pandas/tests/test_frame.py

+12
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ def test_setitem(self):
8989
self.assertEqual(smaller['col10'].dtype, np.object_)
9090
self.assert_((smaller['col10'] == ['1', '2']).all())
9191

92+
def test_setitem_always_copy(self):
93+
s = self.frame['A'].copy()
94+
self.frame['E'] = s
95+
96+
self.frame['E'][5:10] = np.nan
97+
self.assert_(notnull(s[5:10]).all())
98+
9299
def test_setitem_boolean(self):
93100
df = self.frame.copy()
94101
values = self.frame.values
@@ -1277,6 +1284,11 @@ def test_as_matrix(self):
12771284
mat = self.mixed_frame.as_matrix(['foo', 'A'])
12781285
self.assertEqual(mat[0, 0], 'bar')
12791286

1287+
# single block corner case
1288+
mat = self.frame.as_matrix(['A', 'B'])
1289+
expected = self.frame.reindex(columns=['A', 'B']).values
1290+
assert_almost_equal(mat, expected)
1291+
12801292
def test_values(self):
12811293
pass
12821294

pandas/tests/test_series.py

+15
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,21 @@ def test_operators_corner(self):
453453
expected = self.ts.values[:-5] + int_ts.values
454454
self.assert_(np.array_equal(added[:-5], expected))
455455

456+
def test_operators_reverse_object(self):
457+
# GH 56
458+
arr = Series(np.random.randn(10), index=np.arange(10),
459+
dtype=object)
460+
461+
def _check_op(arr, op):
462+
result = op(1., arr)
463+
expected = op(1., arr.astype(float))
464+
assert_series_equal(result.astype(float), expected)
465+
466+
_check_op(arr, operator.add)
467+
_check_op(arr, operator.sub)
468+
_check_op(arr, operator.mul)
469+
_check_op(arr, operator.div)
470+
456471
def test_operators_frame(self):
457472
# rpow does not work with DataFrame
458473
df = DataFrame({'A' : self.ts})

0 commit comments

Comments
 (0)