diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index dd90396c4009e7..bda3d2c4afb86e 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -791,8 +791,6 @@ Other API Changes - Restricted DateOffset keyword arguments. Previously, ``DateOffset`` subclasses allowed arbitrary keyword arguments which could lead to unexpected behavior. Now, only valid arguments will be accepted. (:issue:`17176`). - Pandas no longer registers matplotlib converters on import. The converters will be registered and used when the first plot is draw (:issue:`17710`) -- Setting on a column with a scalar value and 0-len index now raises a ``ValueError`` (:issue:`16823`) - .. _whatsnew_0210.deprecations: diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 3f0aa9d2a1dd23..7db07a187943de 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2557,17 +2557,13 @@ def _ensure_valid_index(self, value): passed value """ # GH5632, make sure that we are a Series convertible - if not len(self.index): - if not is_list_like(value): - # GH16823, Raise an error due to loss of information - raise ValueError('If using all scalar values, you must pass' - ' an index') + if not len(self.index) and is_list_like(value): try: value = Series(value) except: - raise ValueError('Cannot set a frame with no defined' - 'index and a value that cannot be ' - 'converted to a Series') + raise ValueError('Cannot set a frame with no defined index ' + 'and a value that cannot be converted to a ' + 'Series') self._data = self._data.reindex_axis(value.index.copy(), axis=1, fill_value=np.nan) diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index 7ee021e5c62466..a7695bd6f732f8 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -454,9 +454,6 @@ def crosstab(index, columns, values=None, rownames=None, colnames=None, from pandas import DataFrame df = DataFrame(data, index=common_idx) - if not len(df): - return DataFrame(index=common_idx) - if values is None: df['__dummy__'] = 0 kwargs = {'aggfunc': len, 'fill_value': 0} diff --git a/pandas/tests/frame/test_indexing.py b/pandas/tests/frame/test_indexing.py index f850b8f2ee1780..78554d98ab5dfe 100644 --- a/pandas/tests/frame/test_indexing.py +++ b/pandas/tests/frame/test_indexing.py @@ -722,9 +722,11 @@ def test_setitem_empty_frame_with_boolean(self): assert_frame_equal(df, df2) def test_setitem_scalars_no_index(self): - # GH16823 + # GH16823 / 17894 df = DataFrame() - pytest.raises(ValueError, df.__setitem__, 'foo', 1) + df['foo'] = 1 + expected = DataFrame(columns=['foo']).astype(np.int64) + assert_frame_equal(df, expected) def test_getitem_empty_frame_with_boolean(self): # Test for issue #11859 diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index bf3a840aced8c6..c6f38aeba9e87c 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -423,14 +423,15 @@ def test_loc_setitem_consistency(self): def test_loc_setitem_consistency_empty(self): # empty (essentially noops) - # GH16823 + expected = DataFrame(columns=['x', 'y']) + expected['x'] = expected['x'].astype(np.int64) df = DataFrame(columns=['x', 'y']) - with tm.assert_raises_regex(ValueError, 'If using all scalar values'): - df.loc[:, 'x'] = 1 + df.loc[:, 'x'] = 1 + tm.assert_frame_equal(df, expected) df = DataFrame(columns=['x', 'y']) - with tm.assert_raises_regex(ValueError, 'If using all scalar values'): - df['x'] = 1 + df['x'] = 1 + tm.assert_frame_equal(df, expected) def test_loc_setitem_consistency_slice_column_len(self): # .loc[:,column] setting with slice == len of the column diff --git a/pandas/tests/indexing/test_partial.py b/pandas/tests/indexing/test_partial.py index 16f325393649ff..41ddfe934a131f 100644 --- a/pandas/tests/indexing/test_partial.py +++ b/pandas/tests/indexing/test_partial.py @@ -575,16 +575,24 @@ def f(): def test_partial_set_empty_frame_row(self): # GH5720, GH5744 # don't create rows when empty + expected = DataFrame(columns=['A', 'B', 'New'], + index=pd.Index([], dtype='int64')) + expected['A'] = expected['A'].astype('int64') + expected['B'] = expected['B'].astype('float64') + expected['New'] = expected['New'].astype('float64') + df = DataFrame({"A": [1, 2, 3], "B": [1.2, 4.2, 5.2]}) y = df[df.A > 5] - # GH16823 - # Setting a column with a scalar and no index should raise - with tm.assert_raises_regex(ValueError, 'If using all scalar values'): - y['New'] = np.nan + y['New'] = np.nan + tm.assert_frame_equal(y, expected) + # tm.assert_frame_equal(y,expected) + expected = DataFrame(columns=['a', 'b', 'c c', 'd']) + expected['d'] = expected['d'].astype('int64') df = DataFrame(columns=['a', 'b', 'c c']) - with tm.assert_raises_regex(ValueError, 'If using all scalar values'): - df['d'] = 3 + df['d'] = 3 + tm.assert_frame_equal(df, expected) + tm.assert_series_equal(df['c c'], Series(name='c c', dtype=object)) # reindex columns is ok df = DataFrame({"A": [1, 2, 3], "B": [1.2, 4.2, 5.2]}) diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py index 90afd2e2160452..e3951634baca9c 100644 --- a/pandas/tests/reshape/test_pivot.py +++ b/pandas/tests/reshape/test_pivot.py @@ -1228,8 +1228,7 @@ def test_crosstab_no_overlap(self): s2 = pd.Series([4, 5, 6], index=[4, 5, 6]) actual = crosstab(s1, s2) - expected = pd.DataFrame( - index=pd.Index([], dtype='int64')).astype('int64') + expected = pd.DataFrame() tm.assert_frame_equal(actual, expected)