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.