Skip to content

Commit add7189

Browse files
committed
Raise ValueError when settings scalars with 0-len index
1 parent def3bce commit add7189

File tree

7 files changed

+29
-25
lines changed

7 files changed

+29
-25
lines changed

doc/source/whatsnew/v0.21.0.txt

+2
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,8 @@ Other API Changes
591591
- Bug in :func:`DataFrame.drop` caused boolean labels ``False`` and ``True`` to be treated as labels 0 and 1 respectively when dropping indices from a numeric index. This will now raise a ValueError (:issue:`16877`)
592592
- Pandas no longer registers matplotlib converters on import. The converters
593593
will be registered and used when the first plot is draw (:issue:`17710`)
594+
- Setting on a column with a scalar value and 0-len index now raises a ``ValueError`` (:issue:`16823`)
595+
594596

595597
.. _whatsnew_0210.deprecations:
596598

pandas/core/frame.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -2501,13 +2501,17 @@ def _ensure_valid_index(self, value):
25012501
passed value
25022502
"""
25032503
# GH5632, make sure that we are a Series convertible
2504-
if not len(self.index) and is_list_like(value):
2504+
if not len(self.index):
2505+
if not is_list_like(value):
2506+
# GH16823, Raise an error due to loss of information
2507+
raise ValueError('If using all scalar values, you must pass'
2508+
' an index')
25052509
try:
25062510
value = Series(value)
25072511
except:
2508-
raise ValueError('Cannot set a frame with no defined index '
2509-
'and a value that cannot be converted to a '
2510-
'Series')
2512+
raise ValueError('Cannot set a frame with no defined'
2513+
'index and a value that cannot be '
2514+
'converted to a Series')
25112515

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

pandas/core/reshape/pivot.py

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

+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
@@ -390,15 +390,14 @@ def test_loc_setitem_consistency(self):
390390

391391
def test_loc_setitem_consistency_empty(self):
392392
# empty (essentially noops)
393-
expected = DataFrame(columns=['x', 'y'])
394-
expected['x'] = expected['x'].astype(np.int64)
393+
# GH16823
395394
df = DataFrame(columns=['x', 'y'])
396-
df.loc[:, 'x'] = 1
397-
tm.assert_frame_equal(df, expected)
395+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
396+
df.loc[:, 'x'] = 1
398397

399398
df = DataFrame(columns=['x', 'y'])
400-
df['x'] = 1
401-
tm.assert_frame_equal(df, expected)
399+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
400+
df['x'] = 1
402401

403402
def test_loc_setitem_consistency_slice_column_len(self):
404403
# .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
@@ -523,24 +523,16 @@ def f():
523523
def test_partial_set_empty_frame_row(self):
524524
# GH5720, GH5744
525525
# don't create rows when empty
526-
expected = DataFrame(columns=['A', 'B', 'New'],
527-
index=pd.Index([], dtype='int64'))
528-
expected['A'] = expected['A'].astype('int64')
529-
expected['B'] = expected['B'].astype('float64')
530-
expected['New'] = expected['New'].astype('float64')
531-
532526
df = DataFrame({"A": [1, 2, 3], "B": [1.2, 4.2, 5.2]})
533527
y = df[df.A > 5]
534-
y['New'] = np.nan
535-
tm.assert_frame_equal(y, expected)
536-
# tm.assert_frame_equal(y,expected)
528+
# GH16823
529+
# Setting a column with a scalar and no index should raise
530+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
531+
y['New'] = np.nan
537532

538-
expected = DataFrame(columns=['a', 'b', 'c c', 'd'])
539-
expected['d'] = expected['d'].astype('int64')
540533
df = DataFrame(columns=['a', 'b', 'c c'])
541-
df['d'] = 3
542-
tm.assert_frame_equal(df, expected)
543-
tm.assert_series_equal(df['c c'], Series(name='c c', dtype=object))
534+
with tm.assert_raises_regex(ValueError, 'If using all scalar values'):
535+
df['d'] = 3
544536

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

pandas/tests/reshape/test_pivot.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ def test_crosstab_no_overlap(self):
12251225
s2 = pd.Series([4, 5, 6], index=[4, 5, 6])
12261226

12271227
actual = crosstab(s1, s2)
1228-
expected = pd.DataFrame()
1228+
expected = pd.DataFrame(index=pd.Index([], dtype='int64'))
12291229

12301230
tm.assert_frame_equal(actual, expected)
12311231

0 commit comments

Comments
 (0)