Я так запутался с различными методами индексации, используемыми iloc
в пандах.
Допустим, я пытаюсь преобразовать 1-й Dataframe в 2-й Dataframe. Сначала у меня есть следующий 1-й Dataframe
a_array = [1,2,3,4,5,6,7,8]
a_df = pd.DataFrame(a_array).T
И я собираюсь преобразовать это в 2-й Dataframe с размером 2x4
. Я начну с установки 2-го кадра данных следующим образом:
b_df = pd.DataFrame(columns=range(4),index=range(2))
Затем я использую цикл for, чтобы помочь мне преобразовать a_df
(1-d) в b_df
(2-d) с помощью следующего кода
for i in range(2):
b_df.iloc[i,:] = a_df.iloc[0,i*4:(i+1)*4]
Это только дает мне следующие результаты
0 1 2 3
0 1 2 3 4
1 NaN NaN NaN NaN
Но когда я изменился b_df.iloc[i,:]
на b_df.iloc[i][:]
. Результат правильный, как следующий, что я хочу
0 1 2 3
0 1 2 3 4
1 5 6 7 8
Может ли кто-нибудь объяснить мне, в чем разница между .iloc[i,:]
и .iloc[i][:]
, и почему .iloc[i][:]
работал в моем примере выше, но не.iloc[i,:]
b_df.iloc[1] = a_df.iloc[0, 4:8]
назначает серию с индексом[4, 5, 6, 7]
серии с индексом[0, 1, 2, 3]
. Нет перекрытия, поэтомуNaN
s присваивается всем элементам. До этого момента это имеет смысл для меня. Но, как и вам, мне непонятно, почемуb_df.iloc[1][:] = ...
ведет себя по-разному - проверяет объектыb_df.iloc[1]
и неb_df.iloc[1][:]
обнаруживает разницы между показателями. Моим лучшим предположением будет то, что назначение непосредственно copy ([:]
) рассматривается Pandas как особый случай, который заставляет его игнорировать индекс правопреемника и создавать это несоответствие.Ответы:
Существует очень, очень большая разница между
series.iloc[:]
иseries[:]
при назначении назад.(i)loc
всегда проверяет, соответствует ли то, что вы назначаете, индексу уполномоченного. Между тем[:]
синтаксис присваивается базовому массиву NumPy, минуя выравнивание индекса.Теперь, когда вы понимаете разницу, давайте посмотрим, что происходит в вашем коде. Просто распечатайте RHS ваших петель, чтобы увидеть, что вы назначаете:
При назначении
b_df.iloc[i, :]
на второй итерации индексы отличаются, поэтому ничего не назначается, и вы видите только NaN. Однако, изменениеb_df.iloc[i, :]
наb_df.iloc[i][:]
означает, что вы присваиваете базовый массив NumPy, поэтому выравнивание индексации обходится. Эта операция лучше выражается какСтоит также упомянуть, что это форма цепного присваивания, что нехорошо , а также затрудняет чтение и понимание вашего кода.
источник
[:]
синтаксис присваивается базовому массиву NumPy»?Разница в том, что в первом случае интерпретатор Python выполнял код следующим образом:
где значение будет в правой части уравнения. Тогда как во втором случае интерпретатор Python выполнил код следующим образом:
где снова значение будет в правой части уравнения.
В каждом из этих двух случаев в setitem будет вызываться другой метод из-за разницы в ключах (i, slice (None)) и slice (None). Следовательно, мы ведем себя по-разному.
источник
b_df.iloc[i]
иb_df.iloc[i][:]
имеют те же показатели, хотя. Почему вы можете назначить серию с несовпадающим индексом одному, а другому - нет?Разница между
.iloc[i,:]
и.iloc[i][:]
В случае, если
.iloc[i,:]
вы обращаетесь непосредственно к конкретной возможностиDataFrame
, выбрав все (:
) столбцы вi
строке. Насколько я знаю, это эквивалентно оставить 2-е измерение неуказанным (.iloc[i]
).В случае
.iloc[i][:]
вы выполняете 2 цепных операций. Таким образом, результат.iloc[i]
будет зависеть от[:]
. Использование этого для установки значений не приветствуется самой Пандой здесь с предупреждением, поэтому вы не должны использовать его:Как упомянул @Scott в комментариях OP, выравнивание данных является внутренним , поэтому индексы в правой части
=
не будут включены, если их нет в левой части. Вот почемуNaN
во втором ряду есть значения.Таким образом, чтобы все было ясно, вы можете сделать следующее:
Или вы можете конвертировать
list
вместо использованияreset_index
:источник