Я ожидаю странного поведения панд. В следующем коде
import numpy as np
import pandas as pd
def info(df):
print(f"whole df: {hex(id(df))}")
print(f"col a : {hex(id(df['a']))}")
print(f"col b : {hex(id(df['b']))}")
print(f"col c : {hex(id(df['c']))}")
def _drop(col):
print(f"called on : {col.name}")
print(f"before drop: {hex(id(col))}")
col[0] = -1
col.dropna(inplace=True)
col[0] = 1
print(f"after drop : {hex(id(col))}")
df = pd.DataFrame([[np.nan, 1.2, np.nan],
[5.8, np.nan, np.nan]], columns=['a', 'b', 'c'])
info(df)
df.apply(_drop)
info(df)
если я закомментирую строку dropna()
или вызову dropna(inplace=False)
, я получу ожидаемый результат (потому что dropna
создает копию, а я изменяю исходную серию):
a b c
0 1.0 1.0 1.0
1 5.8 NaN NaN
Но когда dropna(inplace=True)
операция должна выполняться на месте, тем самым изменяя исходный ряд, но результат, который я получаю, таков:
a b c
0 -1.0 -1.0 -1.0
1 5.8 NaN NaN
Однако я ожидаю, что результат будет таким же, как и в предыдущих случаях. Возвращает ли операция dropna
клон, даже если операция выполняется? Я использую панды версии 0.23.1.
Изменить. На основе предоставленных ответов я добавил hex(ids())
вызовов для проверки реальных экземпляров. Приведенный выше код напечатал это (значения могут отличаться для вас, но равенство между ними должно быть одинаковым)
whole df : 0x1f482392f28
col a : 0x1f482392f60
col b : 0x1f48452af98
col c : 0x1f48452ada0
called on : a
before drop: 0x1f480dcc2e8
after drop : 0x1f480dcc2e8
called on : b
before drop: 0x1f480dcc2e8
after drop : 0x1f480dcc2e8
called on : a
before drop: 0x1f480dcc2e8
after drop : 0x1f480dcc2e8
called on : b
before drop: 0x1f4ffef1ef0
after drop : 0x1f4ffef1ef0
called on : c
before drop: 0x1f480dcc2e8
after drop : 0x1f480dcc2e8
whole df : 0x1f482392f28
col a : 0x1f482392f60
col b : 0x1f48452af98
col c : 0x1f48452ada0
Странно, что функция вызывается 2 раза для столбцов a
и b
, однако docs говорит, что он вызывается дважды только для первого столбца.
Кроме того, шестнадцатеричное значение для второго прохода столбца b
отличается. И то, и другое не происходит, если col.drop()
опущено.
Шестнадцатеричные значения предполагают, что .apply()
создает новую копию столбцов, однако то, как она распространяет значения обратно в исходное df
, мне неизвестно.
print(hex(id(col)))
к функции, вы увидите, что копирование не выполняется. - person Thomas   schedule 16.07.2018