Skip to content

Commit ae8323b

Browse files
alanbatojreback
authored andcommitted
Raise ValueError when settings scalars with 0-len index
1 parent e63c935 commit ae8323b

File tree

7 files changed

+29
-25
lines changed

7 files changed

+29
-25
lines changed

doc/source/whatsnew/v0.21.0.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,8 @@ Other API Changes
706706
- 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`).
707707
- Pandas no longer registers matplotlib converters on import. The converters
708708
will be registered and used when the first plot is draw (:issue:`17710`)
709+
- Setting on a column with a scalar value and 0-len index now raises a ``ValueError`` (:issue:`16823`)
710+
709711

710712
.. _whatsnew_0210.deprecations:
711713

pandas/core/frame.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2531,13 +2531,17 @@ def _ensure_valid_index(self, value):
25312531
passed value
25322532
"""
25332533
# GH5632, make sure that we are a Series convertible
2534-
if not len(self.index) and is_list_like(value):
2534+
if not len(self.index):
2535+
if not is_list_like(value):
2536+
# GH16823, Raise an error due to loss of information
2537+
raise ValueError('If using all scalar values, you must pass'
2538+
' an index')
25352539
try:
25362540
value = Series(value)
25372541
except:
2538-
raise ValueError('Cannot set a frame with no defined index '
2539-
'and a value that cannot be converted to a '
2540-
'Series')
2542+
raise ValueError('Cannot set a frame with no defined'
2543+
'index and a value that cannot be '
2544+
'converted to a Series')
25412545

25422546
self._data = self._data.reindex_axis(value.index.copy(), axis=1,
25432547
fill_value=np.nan)

pandas/core/reshape/pivot.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ def crosstab(index, columns, values=None, rownames=None, colnames=None,
454454

455455
from pandas import DataFrame
456456
df = DataFrame(data, index=common_idx)
457+
if not len(df):
458+
return DataFrame(index=common_idx)
457459
if values is None:
458460
df['__dummy__'] = 0
459461
kwargs = {'aggfunc': len, 'fill_value': 0}

pandas/tests/frame/test_indexing.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,11 @@ def test_setitem_empty_frame_with_boolean(self):
721721
df[df > df2] = 47
722722
assert_frame_equal(df, df2)
723723

724+
def test_setitem_scalars_no_index(self):
725+
# GH16823
726+
df = DataFrame()
727+
pytest.raises(ValueError, df.__setitem__, 'foo', 1)
728+
724729
def test_getitem_empty_frame_with_boolean(self):
725730
# Test for issue #11859
726731

pandas/tests/indexing/test_loc.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,15 +423,14 @@ def test_loc_setitem_consistency(self):
423423

424424
def test_loc_setitem_consistency_empty(self):
425425
# empty (essentially noops)
426-
expected = DataFrame(columns=['x', 'y'])
427-
expected['x'] = expected['x'].astype(np.int64)
426+
# GH16823
428427
df = DataFrame(columns=['x', 'y'])
429-
df.loc[:, 'x'] = 1
430-
tm.assert_frame_equal(df, expected)
428+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
429+
df.loc[:, 'x'] = 1
431430

432431
df = DataFrame(columns=['x', 'y'])
433-
df['x'] = 1
434-
tm.assert_frame_equal(df, expected)
432+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
433+
df['x'] = 1
435434

436435
def test_loc_setitem_consistency_slice_column_len(self):
437436
# .loc[:,column] setting with slice == len of the column

pandas/tests/indexing/test_partial.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -575,24 +575,16 @@ def f():
575575
def test_partial_set_empty_frame_row(self):
576576
# GH5720, GH5744
577577
# don't create rows when empty
578-
expected = DataFrame(columns=['A', 'B', 'New'],
579-
index=pd.Index([], dtype='int64'))
580-
expected['A'] = expected['A'].astype('int64')
581-
expected['B'] = expected['B'].astype('float64')
582-
expected['New'] = expected['New'].astype('float64')
583-
584578
df = DataFrame({"A": [1, 2, 3], "B": [1.2, 4.2, 5.2]})
585579
y = df[df.A > 5]
586-
y['New'] = np.nan
587-
tm.assert_frame_equal(y, expected)
588-
# tm.assert_frame_equal(y,expected)
580+
# GH16823
581+
# Setting a column with a scalar and no index should raise
582+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
583+
y['New'] = np.nan
589584

590-
expected = DataFrame(columns=['a', 'b', 'c c', 'd'])
591-
expected['d'] = expected['d'].astype('int64')
592585
df = DataFrame(columns=['a', 'b', 'c c'])
593-
df['d'] = 3
594-
tm.assert_frame_equal(df, expected)
595-
tm.assert_series_equal(df['c c'], Series(name='c c', dtype=object))
586+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
587+
df['d'] = 3
596588

597589
# reindex columns is ok
598590
df = DataFrame({"A": [1, 2, 3], "B": [1.2, 4.2, 5.2]})

pandas/tests/reshape/test_pivot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,7 @@ def test_crosstab_no_overlap(self):
12261226
s2 = pd.Series([4, 5, 6], index=[4, 5, 6])
12271227

12281228
actual = crosstab(s1, s2)
1229-
expected = pd.DataFrame()
1229+
expected = pd.DataFrame(index=pd.Index([], dtype='int64'))
12301230

12311231
tm.assert_frame_equal(actual, expected)
12321232

0 commit comments

Comments
 (0)