172 lines
4.8 KiB
Python
172 lines
4.8 KiB
Python
import numpy as np
|
|
import pytest
|
|
|
|
from pandas import (
|
|
DataFrame,
|
|
MultiIndex,
|
|
Series,
|
|
)
|
|
import pandas._testing as tm
|
|
|
|
|
|
@pytest.fixture
|
|
def simple_multiindex_dataframe():
|
|
"""
|
|
Factory function to create simple 3 x 3 dataframe with
|
|
both columns and row MultiIndex using supplied data or
|
|
random data by default.
|
|
"""
|
|
|
|
data = np.random.default_rng(2).standard_normal((3, 3))
|
|
return DataFrame(
|
|
data, columns=[[2, 2, 4], [6, 8, 10]], index=[[4, 4, 8], [8, 10, 12]]
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"indexer, expected",
|
|
[
|
|
(
|
|
lambda df: df.iloc[0],
|
|
lambda arr: Series(arr[0], index=[[2, 2, 4], [6, 8, 10]], name=(4, 8)),
|
|
),
|
|
(
|
|
lambda df: df.iloc[2],
|
|
lambda arr: Series(arr[2], index=[[2, 2, 4], [6, 8, 10]], name=(8, 12)),
|
|
),
|
|
(
|
|
lambda df: df.iloc[:, 2],
|
|
lambda arr: Series(arr[:, 2], index=[[4, 4, 8], [8, 10, 12]], name=(4, 10)),
|
|
),
|
|
],
|
|
)
|
|
def test_iloc_returns_series(indexer, expected, simple_multiindex_dataframe):
|
|
df = simple_multiindex_dataframe
|
|
arr = df.values
|
|
result = indexer(df)
|
|
expected = expected(arr)
|
|
tm.assert_series_equal(result, expected)
|
|
|
|
|
|
def test_iloc_returns_dataframe(simple_multiindex_dataframe):
|
|
df = simple_multiindex_dataframe
|
|
result = df.iloc[[0, 1]]
|
|
expected = df.xs(4, drop_level=False)
|
|
tm.assert_frame_equal(result, expected)
|
|
|
|
|
|
def test_iloc_returns_scalar(simple_multiindex_dataframe):
|
|
df = simple_multiindex_dataframe
|
|
arr = df.values
|
|
result = df.iloc[2, 2]
|
|
expected = arr[2, 2]
|
|
assert result == expected
|
|
|
|
|
|
def test_iloc_getitem_multiple_items():
|
|
# GH 5528
|
|
tup = zip(*[["a", "a", "b", "b"], ["x", "y", "x", "y"]])
|
|
index = MultiIndex.from_tuples(tup)
|
|
df = DataFrame(np.random.default_rng(2).standard_normal((4, 4)), index=index)
|
|
result = df.iloc[[2, 3]]
|
|
expected = df.xs("b", drop_level=False)
|
|
tm.assert_frame_equal(result, expected)
|
|
|
|
|
|
def test_iloc_getitem_labels():
|
|
# this is basically regular indexing
|
|
arr = np.random.default_rng(2).standard_normal((4, 3))
|
|
df = DataFrame(
|
|
arr,
|
|
columns=[["i", "i", "j"], ["A", "A", "B"]],
|
|
index=[["i", "i", "j", "k"], ["X", "X", "Y", "Y"]],
|
|
)
|
|
result = df.iloc[2, 2]
|
|
expected = arr[2, 2]
|
|
assert result == expected
|
|
|
|
|
|
def test_frame_getitem_slice(multiindex_dataframe_random_data):
|
|
df = multiindex_dataframe_random_data
|
|
result = df.iloc[:4]
|
|
expected = df[:4]
|
|
tm.assert_frame_equal(result, expected)
|
|
|
|
|
|
def test_frame_setitem_slice(multiindex_dataframe_random_data):
|
|
df = multiindex_dataframe_random_data
|
|
df.iloc[:4] = 0
|
|
|
|
assert (df.values[:4] == 0).all()
|
|
assert (df.values[4:] != 0).all()
|
|
|
|
|
|
def test_indexing_ambiguity_bug_1678():
|
|
# GH 1678
|
|
columns = MultiIndex.from_tuples(
|
|
[("Ohio", "Green"), ("Ohio", "Red"), ("Colorado", "Green")]
|
|
)
|
|
index = MultiIndex.from_tuples([("a", 1), ("a", 2), ("b", 1), ("b", 2)])
|
|
|
|
df = DataFrame(np.arange(12).reshape((4, 3)), index=index, columns=columns)
|
|
|
|
result = df.iloc[:, 1]
|
|
expected = df.loc[:, ("Ohio", "Red")]
|
|
tm.assert_series_equal(result, expected)
|
|
|
|
|
|
def test_iloc_integer_locations():
|
|
# GH 13797
|
|
data = [
|
|
["str00", "str01"],
|
|
["str10", "str11"],
|
|
["str20", "srt21"],
|
|
["str30", "str31"],
|
|
["str40", "str41"],
|
|
]
|
|
|
|
index = MultiIndex.from_tuples(
|
|
[("CC", "A"), ("CC", "B"), ("CC", "B"), ("BB", "a"), ("BB", "b")]
|
|
)
|
|
|
|
expected = DataFrame(data)
|
|
df = DataFrame(data, index=index)
|
|
|
|
result = DataFrame([[df.iloc[r, c] for c in range(2)] for r in range(5)])
|
|
|
|
tm.assert_frame_equal(result, expected)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"data, indexes, values, expected_k",
|
|
[
|
|
# test without indexer value in first level of MultiIndex
|
|
([[2, 22, 5], [2, 33, 6]], [0, -1, 1], [2, 3, 1], [7, 10]),
|
|
# test like code sample 1 in the issue
|
|
([[1, 22, 555], [1, 33, 666]], [0, -1, 1], [200, 300, 100], [755, 1066]),
|
|
# test like code sample 2 in the issue
|
|
([[1, 3, 7], [2, 4, 8]], [0, -1, 1], [10, 10, 1000], [17, 1018]),
|
|
# test like code sample 3 in the issue
|
|
([[1, 11, 4], [2, 22, 5], [3, 33, 6]], [0, -1, 1], [4, 7, 10], [8, 15, 13]),
|
|
],
|
|
)
|
|
def test_iloc_setitem_int_multiindex_series(data, indexes, values, expected_k):
|
|
# GH17148
|
|
df = DataFrame(data=data, columns=["i", "j", "k"])
|
|
df = df.set_index(["i", "j"])
|
|
|
|
series = df.k.copy()
|
|
for i, v in zip(indexes, values):
|
|
series.iloc[i] += v
|
|
|
|
df["k"] = expected_k
|
|
expected = df.k
|
|
tm.assert_series_equal(series, expected)
|
|
|
|
|
|
def test_getitem_iloc(multiindex_dataframe_random_data):
|
|
df = multiindex_dataframe_random_data
|
|
result = df.iloc[2]
|
|
expected = df.xs(df.index[2])
|
|
tm.assert_series_equal(result, expected)
|