mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-12-24 22:44:56 +01:00
416 lines
13 KiB
Python
416 lines
13 KiB
Python
|
""" test scalar indexing, including at and iat """
|
||
|
from datetime import datetime, timedelta
|
||
|
|
||
|
import numpy as np
|
||
|
import pytest
|
||
|
|
||
|
from pandas import DataFrame, Series, Timedelta, Timestamp, date_range, period_range
|
||
|
import pandas._testing as tm
|
||
|
from pandas.tests.indexing.common import Base
|
||
|
|
||
|
|
||
|
class TestScalar(Base):
|
||
|
@pytest.mark.parametrize("kind", ["series", "frame"])
|
||
|
def test_at_and_iat_get(self, kind):
|
||
|
def _check(f, func, values=False):
|
||
|
|
||
|
if f is not None:
|
||
|
indices = self.generate_indices(f, values)
|
||
|
for i in indices:
|
||
|
result = getattr(f, func)[i]
|
||
|
expected = self.get_value(func, f, i, values)
|
||
|
tm.assert_almost_equal(result, expected)
|
||
|
|
||
|
d = getattr(self, kind)
|
||
|
|
||
|
# iat
|
||
|
for f in [d["ints"], d["uints"]]:
|
||
|
_check(f, "iat", values=True)
|
||
|
|
||
|
for f in [d["labels"], d["ts"], d["floats"]]:
|
||
|
if f is not None:
|
||
|
msg = "iAt based indexing can only have integer indexers"
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
self.check_values(f, "iat")
|
||
|
|
||
|
# at
|
||
|
for f in [d["ints"], d["uints"], d["labels"], d["ts"], d["floats"]]:
|
||
|
_check(f, "at")
|
||
|
|
||
|
@pytest.mark.parametrize("kind", ["series", "frame"])
|
||
|
def test_at_and_iat_set(self, kind):
|
||
|
def _check(f, func, values=False):
|
||
|
|
||
|
if f is not None:
|
||
|
indices = self.generate_indices(f, values)
|
||
|
for i in indices:
|
||
|
getattr(f, func)[i] = 1
|
||
|
expected = self.get_value(func, f, i, values)
|
||
|
tm.assert_almost_equal(expected, 1)
|
||
|
|
||
|
d = getattr(self, kind)
|
||
|
|
||
|
# iat
|
||
|
for f in [d["ints"], d["uints"]]:
|
||
|
_check(f, "iat", values=True)
|
||
|
|
||
|
for f in [d["labels"], d["ts"], d["floats"]]:
|
||
|
if f is not None:
|
||
|
msg = "iAt based indexing can only have integer indexers"
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
_check(f, "iat")
|
||
|
|
||
|
# at
|
||
|
for f in [d["ints"], d["uints"], d["labels"], d["ts"], d["floats"]]:
|
||
|
_check(f, "at")
|
||
|
|
||
|
|
||
|
class TestScalar2:
|
||
|
# TODO: Better name, just separating things that dont need Base class
|
||
|
|
||
|
def test_at_iat_coercion(self):
|
||
|
|
||
|
# as timestamp is not a tuple!
|
||
|
dates = date_range("1/1/2000", periods=8)
|
||
|
df = DataFrame(np.random.randn(8, 4), index=dates, columns=["A", "B", "C", "D"])
|
||
|
s = df["A"]
|
||
|
|
||
|
result = s.at[dates[5]]
|
||
|
xp = s.values[5]
|
||
|
assert result == xp
|
||
|
|
||
|
# GH 7729
|
||
|
# make sure we are boxing the returns
|
||
|
s = Series(["2014-01-01", "2014-02-02"], dtype="datetime64[ns]")
|
||
|
expected = Timestamp("2014-02-02")
|
||
|
|
||
|
for r in [lambda: s.iat[1], lambda: s.iloc[1]]:
|
||
|
result = r()
|
||
|
assert result == expected
|
||
|
|
||
|
s = Series(["1 days", "2 days"], dtype="timedelta64[ns]")
|
||
|
expected = Timedelta("2 days")
|
||
|
|
||
|
for r in [lambda: s.iat[1], lambda: s.iloc[1]]:
|
||
|
result = r()
|
||
|
assert result == expected
|
||
|
|
||
|
def test_iat_invalid_args(self):
|
||
|
pass
|
||
|
|
||
|
def test_imethods_with_dups(self):
|
||
|
|
||
|
# GH6493
|
||
|
# iat/iloc with dups
|
||
|
|
||
|
s = Series(range(5), index=[1, 1, 2, 2, 3], dtype="int64")
|
||
|
result = s.iloc[2]
|
||
|
assert result == 2
|
||
|
result = s.iat[2]
|
||
|
assert result == 2
|
||
|
|
||
|
msg = "index 10 is out of bounds for axis 0 with size 5"
|
||
|
with pytest.raises(IndexError, match=msg):
|
||
|
s.iat[10]
|
||
|
msg = "index -10 is out of bounds for axis 0 with size 5"
|
||
|
with pytest.raises(IndexError, match=msg):
|
||
|
s.iat[-10]
|
||
|
|
||
|
result = s.iloc[[2, 3]]
|
||
|
expected = Series([2, 3], [2, 2], dtype="int64")
|
||
|
tm.assert_series_equal(result, expected)
|
||
|
|
||
|
df = s.to_frame()
|
||
|
result = df.iloc[2]
|
||
|
expected = Series(2, index=[0], name=2)
|
||
|
tm.assert_series_equal(result, expected)
|
||
|
|
||
|
result = df.iat[2, 0]
|
||
|
assert result == 2
|
||
|
|
||
|
def test_frame_at_with_duplicate_axes(self):
|
||
|
# GH#33041
|
||
|
arr = np.random.randn(6).reshape(3, 2)
|
||
|
df = DataFrame(arr, columns=["A", "A"])
|
||
|
|
||
|
result = df.at[0, "A"]
|
||
|
expected = df.iloc[0]
|
||
|
|
||
|
tm.assert_series_equal(result, expected)
|
||
|
|
||
|
result = df.T.at["A", 0]
|
||
|
tm.assert_series_equal(result, expected)
|
||
|
|
||
|
# setter
|
||
|
df.at[1, "A"] = 2
|
||
|
expected = Series([2.0, 2.0], index=["A", "A"], name=1)
|
||
|
tm.assert_series_equal(df.iloc[1], expected)
|
||
|
|
||
|
def test_frame_at_with_duplicate_axes_requires_scalar_lookup(self):
|
||
|
# GH#33041 check that falling back to loc doesn't allow non-scalar
|
||
|
# args to slip in
|
||
|
|
||
|
arr = np.random.randn(6).reshape(3, 2)
|
||
|
df = DataFrame(arr, columns=["A", "A"])
|
||
|
|
||
|
msg = "Invalid call for scalar access"
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
df.at[[1, 2]]
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
df.at[1, ["A"]]
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
df.at[:, "A"]
|
||
|
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
df.at[[1, 2]] = 1
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
df.at[1, ["A"]] = 1
|
||
|
with pytest.raises(ValueError, match=msg):
|
||
|
df.at[:, "A"] = 1
|
||
|
|
||
|
def test_series_at_raises_type_error(self):
|
||
|
# at should not fallback
|
||
|
# GH 7814
|
||
|
# GH#31724 .at should match .loc
|
||
|
ser = Series([1, 2, 3], index=list("abc"))
|
||
|
result = ser.at["a"]
|
||
|
assert result == 1
|
||
|
result = ser.loc["a"]
|
||
|
assert result == 1
|
||
|
|
||
|
with pytest.raises(KeyError, match="^0$"):
|
||
|
ser.at[0]
|
||
|
with pytest.raises(KeyError, match="^0$"):
|
||
|
ser.loc[0]
|
||
|
|
||
|
def test_frame_raises_key_error(self):
|
||
|
# GH#31724 .at should match .loc
|
||
|
df = DataFrame({"A": [1, 2, 3]}, index=list("abc"))
|
||
|
result = df.at["a", "A"]
|
||
|
assert result == 1
|
||
|
result = df.loc["a", "A"]
|
||
|
assert result == 1
|
||
|
|
||
|
with pytest.raises(KeyError, match="^0$"):
|
||
|
df.at["a", 0]
|
||
|
with pytest.raises(KeyError, match="^0$"):
|
||
|
df.loc["a", 0]
|
||
|
|
||
|
def test_series_at_raises_key_error(self):
|
||
|
# GH#31724 .at should match .loc
|
||
|
|
||
|
ser = Series([1, 2, 3], index=[3, 2, 1])
|
||
|
result = ser.at[1]
|
||
|
assert result == 3
|
||
|
result = ser.loc[1]
|
||
|
assert result == 3
|
||
|
|
||
|
with pytest.raises(KeyError, match="a"):
|
||
|
ser.at["a"]
|
||
|
with pytest.raises(KeyError, match="a"):
|
||
|
# .at should match .loc
|
||
|
ser.loc["a"]
|
||
|
|
||
|
def test_frame_at_raises_key_error(self):
|
||
|
# GH#31724 .at should match .loc
|
||
|
|
||
|
df = DataFrame({0: [1, 2, 3]}, index=[3, 2, 1])
|
||
|
|
||
|
result = df.at[1, 0]
|
||
|
assert result == 3
|
||
|
result = df.loc[1, 0]
|
||
|
assert result == 3
|
||
|
|
||
|
with pytest.raises(KeyError, match="a"):
|
||
|
df.at["a", 0]
|
||
|
with pytest.raises(KeyError, match="a"):
|
||
|
df.loc["a", 0]
|
||
|
|
||
|
with pytest.raises(KeyError, match="a"):
|
||
|
df.at[1, "a"]
|
||
|
with pytest.raises(KeyError, match="a"):
|
||
|
df.loc[1, "a"]
|
||
|
|
||
|
# TODO: belongs somewhere else?
|
||
|
def test_getitem_list_missing_key(self):
|
||
|
# GH 13822, incorrect error string with non-unique columns when missing
|
||
|
# column is accessed
|
||
|
df = DataFrame({"x": [1.0], "y": [2.0], "z": [3.0]})
|
||
|
df.columns = ["x", "x", "z"]
|
||
|
|
||
|
# Check that we get the correct value in the KeyError
|
||
|
with pytest.raises(KeyError, match=r"\['y'\] not in index"):
|
||
|
df[["x", "y", "z"]]
|
||
|
|
||
|
def test_at_with_tz(self):
|
||
|
# gh-15822
|
||
|
df = DataFrame(
|
||
|
{
|
||
|
"name": ["John", "Anderson"],
|
||
|
"date": [
|
||
|
Timestamp(2017, 3, 13, 13, 32, 56),
|
||
|
Timestamp(2017, 2, 16, 12, 10, 3),
|
||
|
],
|
||
|
}
|
||
|
)
|
||
|
df["date"] = df["date"].dt.tz_localize("Asia/Shanghai")
|
||
|
|
||
|
expected = Timestamp("2017-03-13 13:32:56+0800", tz="Asia/Shanghai")
|
||
|
|
||
|
result = df.loc[0, "date"]
|
||
|
assert result == expected
|
||
|
|
||
|
result = df.at[0, "date"]
|
||
|
assert result == expected
|
||
|
|
||
|
def test_series_set_tz_timestamp(self, tz_naive_fixture):
|
||
|
# GH 25506
|
||
|
ts = Timestamp("2017-08-05 00:00:00+0100", tz=tz_naive_fixture)
|
||
|
result = Series(ts)
|
||
|
result.at[1] = ts
|
||
|
expected = Series([ts, ts])
|
||
|
tm.assert_series_equal(result, expected)
|
||
|
|
||
|
def test_mixed_index_at_iat_loc_iloc_series(self):
|
||
|
# GH 19860
|
||
|
s = Series([1, 2, 3, 4, 5], index=["a", "b", "c", 1, 2])
|
||
|
for el, item in s.items():
|
||
|
assert s.at[el] == s.loc[el] == item
|
||
|
for i in range(len(s)):
|
||
|
assert s.iat[i] == s.iloc[i] == i + 1
|
||
|
|
||
|
with pytest.raises(KeyError, match="^4$"):
|
||
|
s.at[4]
|
||
|
with pytest.raises(KeyError, match="^4$"):
|
||
|
s.loc[4]
|
||
|
|
||
|
def test_mixed_index_at_iat_loc_iloc_dataframe(self):
|
||
|
# GH 19860
|
||
|
df = DataFrame(
|
||
|
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]], columns=["a", "b", "c", 1, 2]
|
||
|
)
|
||
|
for rowIdx, row in df.iterrows():
|
||
|
for el, item in row.items():
|
||
|
assert df.at[rowIdx, el] == df.loc[rowIdx, el] == item
|
||
|
|
||
|
for row in range(2):
|
||
|
for i in range(5):
|
||
|
assert df.iat[row, i] == df.iloc[row, i] == row * 5 + i
|
||
|
|
||
|
with pytest.raises(KeyError, match="^3$"):
|
||
|
df.at[0, 3]
|
||
|
with pytest.raises(KeyError, match="^3$"):
|
||
|
df.loc[0, 3]
|
||
|
|
||
|
def test_iat_setter_incompatible_assignment(self):
|
||
|
# GH 23236
|
||
|
result = DataFrame({"a": [0, 1], "b": [4, 5]})
|
||
|
result.iat[0, 0] = None
|
||
|
expected = DataFrame({"a": [None, 1], "b": [4, 5]})
|
||
|
tm.assert_frame_equal(result, expected)
|
||
|
|
||
|
def test_getitem_zerodim_np_array(self):
|
||
|
# GH24924
|
||
|
# dataframe __getitem__
|
||
|
df = DataFrame([[1, 2], [3, 4]])
|
||
|
result = df[np.array(0)]
|
||
|
expected = Series([1, 3], name=0)
|
||
|
tm.assert_series_equal(result, expected)
|
||
|
|
||
|
# series __getitem__
|
||
|
s = Series([1, 2])
|
||
|
result = s[np.array(0)]
|
||
|
assert result == 1
|
||
|
|
||
|
|
||
|
def test_iat_dont_wrap_object_datetimelike():
|
||
|
# GH#32809 .iat calls go through DataFrame._get_value, should not
|
||
|
# call maybe_box_datetimelike
|
||
|
dti = date_range("2016-01-01", periods=3)
|
||
|
tdi = dti - dti
|
||
|
ser = Series(dti.to_pydatetime(), dtype=object)
|
||
|
ser2 = Series(tdi.to_pytimedelta(), dtype=object)
|
||
|
df = DataFrame({"A": ser, "B": ser2})
|
||
|
assert (df.dtypes == object).all()
|
||
|
|
||
|
for result in [df.at[0, "A"], df.iat[0, 0], df.loc[0, "A"], df.iloc[0, 0]]:
|
||
|
assert result is ser[0]
|
||
|
assert isinstance(result, datetime)
|
||
|
assert not isinstance(result, Timestamp)
|
||
|
|
||
|
for result in [df.at[1, "B"], df.iat[1, 1], df.loc[1, "B"], df.iloc[1, 1]]:
|
||
|
assert result is ser2[1]
|
||
|
assert isinstance(result, timedelta)
|
||
|
assert not isinstance(result, Timedelta)
|
||
|
|
||
|
|
||
|
def test_iat_series_with_period_index():
|
||
|
# GH 4390, iat incorrectly indexing
|
||
|
index = period_range("1/1/2001", periods=10)
|
||
|
ser = Series(np.random.randn(10), index=index)
|
||
|
expected = ser[index[0]]
|
||
|
result = ser.iat[0]
|
||
|
assert expected == result
|
||
|
|
||
|
|
||
|
def test_at_with_tuple_index_get():
|
||
|
# GH 26989
|
||
|
# DataFrame.at getter works with Index of tuples
|
||
|
df = DataFrame({"a": [1, 2]}, index=[(1, 2), (3, 4)])
|
||
|
assert df.index.nlevels == 1
|
||
|
assert df.at[(1, 2), "a"] == 1
|
||
|
|
||
|
# Series.at getter works with Index of tuples
|
||
|
series = df["a"]
|
||
|
assert series.index.nlevels == 1
|
||
|
assert series.at[(1, 2)] == 1
|
||
|
|
||
|
|
||
|
def test_at_with_tuple_index_set():
|
||
|
# GH 26989
|
||
|
# DataFrame.at setter works with Index of tuples
|
||
|
df = DataFrame({"a": [1, 2]}, index=[(1, 2), (3, 4)])
|
||
|
assert df.index.nlevels == 1
|
||
|
df.at[(1, 2), "a"] = 2
|
||
|
assert df.at[(1, 2), "a"] == 2
|
||
|
|
||
|
# Series.at setter works with Index of tuples
|
||
|
series = df["a"]
|
||
|
assert series.index.nlevels == 1
|
||
|
series.at[1, 2] = 3
|
||
|
assert series.at[1, 2] == 3
|
||
|
|
||
|
|
||
|
def test_multiindex_at_get():
|
||
|
# GH 26989
|
||
|
# DataFrame.at and DataFrame.loc getter works with MultiIndex
|
||
|
df = DataFrame({"a": [1, 2]}, index=[[1, 2], [3, 4]])
|
||
|
assert df.index.nlevels == 2
|
||
|
assert df.at[(1, 3), "a"] == 1
|
||
|
assert df.loc[(1, 3), "a"] == 1
|
||
|
|
||
|
# Series.at and Series.loc getter works with MultiIndex
|
||
|
series = df["a"]
|
||
|
assert series.index.nlevels == 2
|
||
|
assert series.at[1, 3] == 1
|
||
|
assert series.loc[1, 3] == 1
|
||
|
|
||
|
|
||
|
def test_multiindex_at_set():
|
||
|
# GH 26989
|
||
|
# DataFrame.at and DataFrame.loc setter works with MultiIndex
|
||
|
df = DataFrame({"a": [1, 2]}, index=[[1, 2], [3, 4]])
|
||
|
assert df.index.nlevels == 2
|
||
|
df.at[(1, 3), "a"] = 3
|
||
|
assert df.at[(1, 3), "a"] == 3
|
||
|
df.loc[(1, 3), "a"] = 4
|
||
|
assert df.loc[(1, 3), "a"] == 4
|
||
|
|
||
|
# Series.at and Series.loc setter works with MultiIndex
|
||
|
series = df["a"]
|
||
|
assert series.index.nlevels == 2
|
||
|
series.at[1, 3] = 5
|
||
|
assert series.at[1, 3] == 5
|
||
|
series.loc[1, 3] = 6
|
||
|
assert series.loc[1, 3] == 6
|