Pandas: Цепочки назначений

Я читал эту ссылку в разделе "Возвращение представления по сравнению с копией". Я действительно не понимаю, как работает связанное назначение в Pandas и как влияет на него использование .ix(), .iloc() или .loc().

Я получаю предупреждения SettingWithCopyWarning для следующих строк кодов, где data - это фреймворк Panda, а amount - это имя столбца (серии) в этом фрейме данных:

data['amount'] = data['amount'].astype(float)

data["amount"].fillna(data.groupby("num")["amount"].transform("mean"), inplace=True)

data["amount"].fillna(mean_avg, inplace=True)

Глядя на этот код, очевидно ли, что я делаю что-то неоптимальное? Если да, можете ли вы сообщить мне строки кода замены?

Я знаю следующее предупреждение и хотел бы думать, что предупреждения в моем случае являются ложными срабатываниями:

Прикомандированные предупреждения/исключения назначений направлены на информирование пользователя возможного недопустимого назначения. Могут быть ложные срабатывания; в ситуациях, когда непреднамеренно сообщается цепочное присвоение.

ИЗМЕНИТЬ: код, приводящий к первой ошибке предупреждения об ошибке.

data['amount'] = data.apply(lambda row: function1(row,date,qty), axis=1) 
data['amount'] = data['amount'].astype(float)

def function1(row,date,qty):
    try:
        if(row['currency'] == 'A'):
            result = row[qty]
        else:
            rate = lookup[lookup['Date']==row[date]][row['currency'] ]
            result = float(rate) * float(row[qty])
        return result
    except ValueError: # generic exception clause
        print "The current row causes an exception:"

Ответ 1

Точка SettingWithCopy должна предупредить пользователя о том, что вы можете делать что-то, что не будет обновлять исходный фрейм данных, как можно было бы ожидать.

Здесь data - это кадр данных, возможно, одного типа (или нет). Затем вы ссылаетесь на эту data['amount'], которая является серией, и обновляете ее. Это, вероятно, работает в вашем случае, потому что вы возвращаете тот же самый тип данных, что и существовали.

Однако он может создать копию, которая обновляет копию data['amount'], которую вы не увидите; Тогда вам будет интересно, почему он не обновляется.

Pandas возвращает копию объекта почти во всех вызовах метода. Операции inplace - это операция проверки, которая работает, но в целом неясно, что данные изменяются и могут потенциально работать с копиями.

Гораздо понятнее сделать это:

data['amount'] = data["amount"].fillna(data.groupby("num")["amount"].transform("mean"))

data["amount"] = data['amount'].fillna(mean_avg)

Еще один плюс к работе над копиями. Вы можете цеплять операции, это невозможно с inplace.

например.

data['amount'] = data['amount'].fillna(mean_avg)*2

И только FYI. Операции inplace не являются эффективными и эффективными. my2c они должны быть запрещены. Но слишком поздно в этом API.

Вы можете, конечно, отключить это:

pd.set_option('chained_assignment',None)

Pandas работает со всем набором тестов с этим набором до raise (так что мы знаем, происходит ли цепочка), FYI.