Skip to content

Commit f9ba6fe

Browse files
alanbatojreback
authored andcommitted
ERR: Raise ValueError when setting scalars in a dataframe with no index ( #16823) (#16968)
1 parent 6e81222 commit f9ba6fe

File tree

7 files changed

+31
-25
lines changed

7 files changed

+31
-25
lines changed

doc/source/whatsnew/v0.21.0.txt

+2
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

+8-4
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

+3
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,9 @@ 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)
459+
457460
if values is None:
458461
df['__dummy__'] = 0
459462
kwargs = {'aggfunc': len, 'fill_value': 0}

pandas/tests/frame/test_indexing.py

+5
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

+5-6
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

+6-14
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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,8 @@ 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(
1230+
index=pd.Index([], dtype='int64')).astype('int64')
12301231

12311232
tm.assert_frame_equal(actual, expected)
12321233

0 commit comments

Comments
 (0)