123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- import operator
- import numpy as np
- import pytest
- import pandas as pd
- from .base import BaseExtensionTests
- class BaseSetitemTests(BaseExtensionTests):
- def test_setitem_scalar_series(self, data, box_in_series):
- if box_in_series:
- data = pd.Series(data)
- data[0] = data[1]
- assert data[0] == data[1]
- def test_setitem_sequence(self, data, box_in_series):
- if box_in_series:
- data = pd.Series(data)
- original = data.copy()
- data[[0, 1]] = [data[1], data[0]]
- assert data[0] == original[1]
- assert data[1] == original[0]
- @pytest.mark.parametrize('as_array', [True, False])
- def test_setitem_sequence_mismatched_length_raises(self, data, as_array):
- ser = pd.Series(data)
- original = ser.copy()
- value = [data[0]]
- if as_array:
- value = data._from_sequence(value)
- xpr = 'cannot set using a {} indexer with a different length'
- with pytest.raises(ValueError, match=xpr.format('list-like')):
- ser[[0, 1]] = value
- # Ensure no modifications made before the exception
- self.assert_series_equal(ser, original)
- with pytest.raises(ValueError, match=xpr.format('slice')):
- ser[slice(3)] = value
- self.assert_series_equal(ser, original)
- def test_setitem_empty_indxer(self, data, box_in_series):
- if box_in_series:
- data = pd.Series(data)
- original = data.copy()
- data[np.array([], dtype=int)] = []
- self.assert_equal(data, original)
- def test_setitem_sequence_broadcasts(self, data, box_in_series):
- if box_in_series:
- data = pd.Series(data)
- data[[0, 1]] = data[2]
- assert data[0] == data[2]
- assert data[1] == data[2]
- @pytest.mark.parametrize('setter', ['loc', 'iloc'])
- def test_setitem_scalar(self, data, setter):
- arr = pd.Series(data)
- setter = getattr(arr, setter)
- operator.setitem(setter, 0, data[1])
- assert arr[0] == data[1]
- def test_setitem_loc_scalar_mixed(self, data):
- df = pd.DataFrame({"A": np.arange(len(data)), "B": data})
- df.loc[0, 'B'] = data[1]
- assert df.loc[0, 'B'] == data[1]
- def test_setitem_loc_scalar_single(self, data):
- df = pd.DataFrame({"B": data})
- df.loc[10, 'B'] = data[1]
- assert df.loc[10, 'B'] == data[1]
- def test_setitem_loc_scalar_multiple_homogoneous(self, data):
- df = pd.DataFrame({"A": data, "B": data})
- df.loc[10, 'B'] = data[1]
- assert df.loc[10, 'B'] == data[1]
- def test_setitem_iloc_scalar_mixed(self, data):
- df = pd.DataFrame({"A": np.arange(len(data)), "B": data})
- df.iloc[0, 1] = data[1]
- assert df.loc[0, 'B'] == data[1]
- def test_setitem_iloc_scalar_single(self, data):
- df = pd.DataFrame({"B": data})
- df.iloc[10, 0] = data[1]
- assert df.loc[10, 'B'] == data[1]
- def test_setitem_iloc_scalar_multiple_homogoneous(self, data):
- df = pd.DataFrame({"A": data, "B": data})
- df.iloc[10, 1] = data[1]
- assert df.loc[10, 'B'] == data[1]
- @pytest.mark.parametrize('as_callable', [True, False])
- @pytest.mark.parametrize('setter', ['loc', None])
- def test_setitem_mask_aligned(self, data, as_callable, setter):
- ser = pd.Series(data)
- mask = np.zeros(len(data), dtype=bool)
- mask[:2] = True
- if as_callable:
- mask2 = lambda x: mask
- else:
- mask2 = mask
- if setter:
- # loc
- target = getattr(ser, setter)
- else:
- # Series.__setitem__
- target = ser
- operator.setitem(target, mask2, data[5:7])
- ser[mask2] = data[5:7]
- assert ser[0] == data[5]
- assert ser[1] == data[6]
- @pytest.mark.parametrize('setter', ['loc', None])
- def test_setitem_mask_broadcast(self, data, setter):
- ser = pd.Series(data)
- mask = np.zeros(len(data), dtype=bool)
- mask[:2] = True
- if setter: # loc
- target = getattr(ser, setter)
- else: # __setitem__
- target = ser
- operator.setitem(target, mask, data[10])
- assert ser[0] == data[10]
- assert ser[1] == data[10]
- def test_setitem_expand_columns(self, data):
- df = pd.DataFrame({"A": data})
- result = df.copy()
- result['B'] = 1
- expected = pd.DataFrame({"A": data, "B": [1] * len(data)})
- self.assert_frame_equal(result, expected)
- result = df.copy()
- result.loc[:, 'B'] = 1
- self.assert_frame_equal(result, expected)
- # overwrite with new type
- result['B'] = data
- expected = pd.DataFrame({"A": data, "B": data})
- self.assert_frame_equal(result, expected)
- def test_setitem_expand_with_extension(self, data):
- df = pd.DataFrame({"A": [1] * len(data)})
- result = df.copy()
- result['B'] = data
- expected = pd.DataFrame({"A": [1] * len(data), "B": data})
- self.assert_frame_equal(result, expected)
- result = df.copy()
- result.loc[:, 'B'] = data
- self.assert_frame_equal(result, expected)
- def test_setitem_frame_invalid_length(self, data):
- df = pd.DataFrame({"A": [1] * len(data)})
- xpr = "Length of values does not match length of index"
- with pytest.raises(ValueError, match=xpr):
- df['B'] = data[:5]
- @pytest.mark.xfail(reason="GH#20441: setitem on extension types.")
- def test_setitem_tuple_index(self, data):
- s = pd.Series(data[:2], index=[(0, 0), (0, 1)])
- expected = pd.Series(data.take([1, 1]), index=s.index)
- s[(0, 1)] = data[1]
- self.assert_series_equal(s, expected)
- def test_setitem_slice_mismatch_length_raises(self, data):
- arr = data[:5]
- with pytest.raises(ValueError):
- arr[:1] = arr[:2]
- def test_setitem_slice_array(self, data):
- arr = data[:5].copy()
- arr[:5] = data[-5:]
- self.assert_extension_array_equal(arr, data[-5:])
- def test_setitem_scalar_key_sequence_raise(self, data):
- arr = data[:5].copy()
- with pytest.raises(ValueError):
- arr[0] = arr[[0, 1]]
|