Чем отличаются методы iloc и loc в pandas
Что проверяют
Понимаете ли вы разницу между меткой строки и её позицией и не путаетесь ли, когда они совпадают. Следом обычно дают таблицу после фильтрации или сортировки и спрашивают, что вернут df.loc[0] и df.iloc[0].
Как отвечать
loc: выборка по меткам индекса и названиям колонок. Принимает метку, список меток, срез меток и булеву маску:df.loc[df["age"] > 30, ["name", "city"]];iloc: выборка по целым позициям от 0, как в списке Python. Принимает число, список чисел, срез и булев массив без индекса;- границы среза:
iloc[0:3]вернёт три строки, правая граница не входит.loc["a":"c"]включает обе границы, у меток нет понятия «следующая после последней»; - скаляры: для одной ячейки есть
atиiat, те жеlocиiloc, но быстрее.
Ради чего вопрос задают на самом деле: у свежего DataFrame индекс RangeIndex, метки совпадают с позициями, и оба метода ведут себя одинаково. Стоит отфильтровать строки или вызвать sort_values, как метки сохраняются, а позиции сдвигаются. Теперь df.loc[0] вернёт строку с меткой 0 или KeyError, если её отфильтровали, а df.iloc[0] просто первую строку.
Про запись тоже спросят. Присваивать нужно одним индексатором: df.loc[mask, "price"] = 0. Цепочка df[mask]["price"] = 0 меняет промежуточный объект: в pandas 2.x это давало SettingWithCopyWarning, а в pandas 3.0, где Copy-on-Write включён по умолчанию, такое присваивание исходную таблицу не меняет никогда.
Где спотыкаются
Говорят, что loc с числом всегда падает. Если индекс целочисленный, loc[5] законно найдёт метку 5, и это вовсе не обязательно шестая строка.
Переносят привычку из Python на loc: ждут, что loc[2:5] вернёт три строки, а получают четыре, потому что правая граница включена.
Передают в iloc булеву Series и получают ValueError. iloc не выравнивает по индексу, ему нужен голый массив, например mask.to_numpy().