Chained assignment что это
Pandas: Chained assignments [duplicate]
I get the SettingWithCopyWarning warnings for the following lines of codes, where data is a Panda dataframe and amount is a column (Series) name in that dataframe:
Looking at this code, is it obvious that I am doing something suboptimal? If so, can you let me know the replacement code lines?
I am aware of the below warning and like to think that the warnings in my case are false positives:
The chained assignment warnings / exceptions are aiming to inform the user of a possibly invalid assignment. There may be false positives; situations where a chained assignment is inadvertantly reported.
EDIT : the code leading to the first copy warning error.
1 Answer 1
The point of the SettingWithCopy is to warn the user that you may be doing something that will not update the original data frame as one might expect.
Here, data is a dataframe, possibly of a single dtype (or not). You are then taking a reference to this data[‘amount’] which is a Series, and updating it. This probably works in your case because you are returning the same dtype of data as existed.
However it could create a copy which updates a copy of data[‘amount’] which you would not see; Then you would be wondering why it is not updating.
Pandas returns a copy of an object in almost all method calls. The inplace operations are a convience operation which work, but in general are not clear that data is being modified and could potentially work on copies.
Much more clear to do this:
One further plus to working on copies. You can chain operations, this is not possible with inplace ones.
And just an FYI. inplace operations are neither faster nor more memory efficient. my2c they should be banned. But too late on that API.
You can of course turn this off:
Pandas runs with the entire test suite with this set to raise (so we know if chaining is happening) on, FYI.
How do chained assignments work?
A quote from something:
Based on my understanding, they should be same because somefunction can only return exactly one value.
6 Answers 6
Note the order. The leftmost target is assigned first. (A similar expression in C may assign in the opposite order.) From the docs on Python assignment:
. assigns the single resulting object to each of the target lists, from left to right.
Disassembly shows this:
CAUTION: the same object is always assigned to each target. So as @Wilduck and @andronikus point out, you probably never want this:
In the above case x and y refer to the same list. Because lists are mutable, appending to x would seem to affect y.
Now you have two names referring to two distinct empty lists.
They will not necessarily work the same if somefunction returns a mutable value. Consider:
What if somefunction() returns different values each time it is called?
It would result in the same only if the function has no side-effects and returns a singleton in a deterministic manner (given its inputs).
Note that the result would be the same, but the process to achieve the result would not:
The content of x and y variables would be the same, but the instruction x = y = slow_is_computer_on() would last 10 seconds, and its counterpart x = slow_is_computer_on() ; y = slow_is_computer_on() would last 20 seconds.
It would be almost the same if the function has no side-effects and returns an immutable in a deterministic manner (given its inputs).
Note that the same catches explained in previous section applies.
Why I say almost? Because of this:
Ok, using is is something strange, but this illustrates that the return is not the same. This is important for the mutable case:
It is dangerous and may lead to bugs if the function returns a mutable
This has also been answered in this question. For the sake of completeness, I replay the argument:
Because in that scenario x and y are the same object, doing an operation like x.append(42) whould mean that both x and y hold a reference to a list which now has 4 elements.
It would not be the same if the function has side-effects
Considering a print a side-effect (which I find valid, but other examples may be used instead):
Instead of a print, it may be a more complex or more subtle side-effect, but the fact remains: the method is called once or twice and that may lead to different behaviour.
It would not be the same if the function is non-deterministic given its inputs
Maybe a simple random method:
But, things related to clock, global counters, system stuff, etc. is sensible to being non-deterministic given the input, and in those cases the value of x and y may diverge.
somefunction will be called twice instead of once.
Even if it returns the same result each time, this will be a noticeable if it takes a minute to return a result! Or if it has a side effect e.g. asking the user for his password.
As already stated by Bob Stein the order of assignment is important; look at the very interesting following case:
Conclusion
This example is more complicated to understand than other ones in other answers, but on the other hand, you can see much quicker that
is not the same as
because the second one will raise an exception if L is not previously defined while the first one will always work.
Волшебное введение в алгоритмы классификации
Перевод статьи Брайна Беренда.
Когда вы впервые приступаете к изучению теории анализа и обработки данных, то одними из первых вы изучаете алгоритмы классификации. Их суть проста: берётся информация о конкретном результате наблюдений (data point), на основании которой этот результат относится к определённой группе или классу.
Хороший пример — спам-фильтр электронной почты. Он должен помечать входящие письма (то есть результаты наблюдений) как «спам» или «не спам», ориентируясь на информацию о письмах (отправитель, количество слов, начинающихся с прописных букв, и так далее).
Это пример хороший, но скучный. Спам-классификацию приводят в качестве примера на лекциях, презентациях и конференциях, так что вы наверняка уже не раз слышали о нём. Но что если поговорить о другом, более интересном алгоритме классификации? Каком-то более странном? Более… волшебном?
Всё верно! Сегодня мы поговорим о Распределяющей шляпе (Sorting Hat) из мира Гарри Поттера. Возьмём какие-то данные из сети, проанализируем и создадим классификатор, который будет сортировать персонажей по разным факультетам. Должно получиться забавно!
Примечание:
Наш классификатор будет не слишком сложным. Так что его нужно рассматривать как «первичный подход» к решению проблемы, демонстрирующий некоторые базовые методики извлечения текста из сети и его анализа. Кроме того, учитывая относительно небольшой размер выборки, мы не будем использовать классические обучающие методики вроде перекрёстной проверки. Мы просто соберём определенные данные, построим простой классификатор на основе правил и оценим результат.
Второе примечание:
Идея этого поста навеяна прекрасной презентацией Брайана Ланга на конференции PyData Chicago 2016. Видеозапись здесь, слайды здесь.
Шаг первый: извлекаем данные из сети
На случай, если последние 20 лет вы провели в пещере: Распределяющая шляпа — это волшебная шляпа, которая помещает поступающих студентов по четырём факультетам Хогвартса: Гриффиндор, Слизерин, Хаффлпафф и Рэйвенклоу. У каждого факультета свои характеристики. Когда шляпу надевают на голову студента, она считывает его разум и определяет, какой факультет подходит ему лучше всего. Согласно этому определению, Распределяющая шляпа — это многоклассовый классификатор (multiclass classifier) (сортирует более чем по двум группам), в отличие от бинарного классификатора (сортирует строго по двум группам), которым является спам-фильтр.
Чтобы распределить студентов по факультетам, нам нужно знать о них определенную информацию. К счастью, достаточно данных есть на harrypotter.wikia.com. На этом сайте лежат статьи почти по всем аспектам вселенной Гарри Поттера, включая описания студентов и факультетов. Приятный бонус: компания Fandom, заведующая сайтом, предоставляет простой в использовании API и массу прекрасной документации. Ура!
Также нам нужно грамотно пройтись по всем студентам Хогвартса и записать факультеты, по которым они раскиданы Распределяющей шляпой (это будут «реальные данные», с которыми мы будем сравнивать результаты нашей сортировки). На сайте статьи разбиты по категориям, вроде «Студенты Хогвартса» и «Фильмы». API позволяет создавать списки статей в рамках конкретной категории.
Возьмём для примера Рэйвенклоу. Закинем все данные в переменную info и затем положим их во фрейм данных (Data Frame) Pandas.
Количество статей: 158
Вы можете проследить полное выполнение анализа с помощью Rodeo!
Примечание:
Если воспользуетесь нашим Python IDE, Rodeo, то просто скопируйте и вставьте вышеприведённый код в Editor или Terminal. Результат вы увидите в окне History или Terminal. Бонус: можно просто перетаскивать окна мышью, меняя их расположение и размер.
На основе этих данных мы узнаем:
Количество статей о студентах: 748
Получение содержаний статей
Имея ID статей, мы можем начать запрашивать содержания. Но некоторые из статей просто ОГРОМНЫ, они содержат невероятное количество подробностей. Вы только взгляните на статьи про Гарри Поттера и Волан-де-Морта!
В статьях про всех ключевых персонажей есть раздел «Личность и черты характера». Логично было бы извлекать отсюда информацию, которую Распределяющая шляпа будет использовать при принятии решений. Но такой раздел есть не во всех статьях, так что если ориентироваться только на него, то количество персонажей сильно уменьшится.
Нижеприведённый код извлекает из каждой статьи раздел «Личность и черты характера» и вычисляет его длину (количество знаков). Затем на основе ID объединяет эти данные с нашим начальным фреймом данных mydf (на это уходит немного времени).
Количество подходящих статей: 94
Шаг второй: Получение характеристик факультетов с помощью NLTK
Теперь мы знаем количество студентов, надо распределить их по факультетам. Для этого составим список характеристик каждого факультета. Начнём собирать из с harrypotter.wikia.com.
Обратите внимание, что все слова — существительные. Это хорошо. Нам нужна консистентность при описании черт характера. Некоторые из них были представлены не в виде существительных, так что приведём их к общему порядку:
К сожалению, это ещё не всё. Вот фраза из раздела «Личность и черты характера» про Невила Лонгботтома:
Когда он был моложе, Невил был неуклюж, забывчив, застенчив, и многие считали, что он плохо подходит для факультета Гриффиндор, потому что он казался робким.
Благодаря поддержке друзей, которым он был очень предан; вдохновению профессора Римуса Люпина предстать перед лицом своих страхов на третьем году обучения; и тому, что мучители его родителей разгуливают на свободе, Невил стал храбрее, увереннее в себе, и самоотверженным в борьбе против Волан-де-Морта и его Пожирателей Смерти.
(When he was younger, Neville was clumsy, forgetful, shy, and many considered him ill-suited for Gryffindor house because he seemed timid.
With the support of his friends, to whom he was very loyal, the encouragement of Professor Remus Lupin to face his fears in his third year, and the motivation of knowing his parents’ torturers were on the loose, Neville became braver, more self-assured, and dedicated to the fight against Lord Voldemort and his Death Eaters.)
Выделенные слова должны засчитываться в пользу каких-то факультетов, но они не будут засчитаны, потому что являются прилагательными. Также не будут учтены слова вроде «bravely» и «braveness». Чтобы наш алгоритм классификации работал правильно, нужно идентифицировать синонимы, антонимы и другие словоформы.
Синонимы
Исследовать синонимы можно с помощью функции synsets из WordNet, лексической базы данных английского языка, включённой в модуль nltk (NLTK — Natural Language Toolkit). “Synset” — это «synonym set», коллекция синонимов, или «лемм». Функция synsets возвращает наборы синонимов, которые ассоциированы с конкретными словами.
Озадачены? Давайте запустим код, а затем разберём его:
Synonym sets associated with the word ‘bravery’: [Synset(‘courage.n.01’), Synset(‘fearlessness.n.01’)]
Synonym sets associated with the word ‘fairness’: [Synset(‘fairness.n.01’), Synset(‘fairness.n.02’), Synset(‘paleness.n.02’), Synset(‘comeliness.n.01’)]
Synonym sets associated with the word ‘wit’: [Synset(‘wit.n.01’), Synset(‘brain.n.02’), Synset(‘wag.n.01’)]
Synonym sets associated with the word ‘cunning’: [Synset(‘craft.n.05’), Synset(‘cunning.n.02’), Synset(‘cunning.s.01’), Synset(‘crafty.s.01’), Synset(‘clever.s.03’)]
Synonym sets associated with the noun ‘cunning’: [Synset(‘craft.n.05’), Synset(‘cunning.n.02’)]
(‘courage.n.01’, [‘courage’, ‘courageousness’, ‘bravery’, ‘braveness’]) (‘fearlessness.n.01’, [‘fearlessness’, ‘bravery’]) (‘fairness.n.01’, [‘fairness’, ‘equity’]) (‘fairness.n.02’, [‘fairness’, ‘fair-mindedness’, ‘candor’, ‘candour’]) (‘paleness.n.02’, [‘paleness’, ‘blondness’, ‘fairness’]) (‘comeliness.n.01’, [‘comeliness’, ‘fairness’, ‘loveliness’, ‘beauteousness’]) (‘wit.n.01’, [‘wit’, ‘humor’, ‘humour’, ‘witticism’, ‘wittiness’]) (‘brain.n.02’, [‘brain’, ‘brainpower’, ‘learning_ability’, ‘mental_capacity’, ‘mentality’, ‘wit’]) (‘wag.n.01’, [‘wag’, ‘wit’, ‘card’]) (‘craft.n.05’, [‘craft’, ‘craftiness’, ‘cunning’, ‘foxiness’, ‘guile’, ‘slyness’, ‘wiliness’]) (‘cunning.n.02’, [‘cunning’])
Так, мы получили много выходных данных. Рассмотрим некоторые моменты и потенциальные проблемы:
Перевод: получить синонимы труднее, чем кажется
Антонимы и словоформы
После того, как мы собрали все синонимы, нужно позаботиться об антонимах и разных словоформах (например, применительно к «bravery» — «brave», «bravely» и «braver»). Немало тяжёлой работы можно выполнить в nltk, но всё же придётся вручную набивать деепричастия и прилагательные в сравнительной / превосходной степени.
Synset: courage.n.01; Lemma: courage; Antonyms: [Lemma(‘cowardice.n.01.cowardice’)]; Word Forms: [Lemma(‘brave.a.01.courageous’)]
Synset: courage.n.01; Lemma: courageousness; Antonyms: []; Word Forms: [Lemma(‘brave.a.01.courageous’)]
Synset: courage.n.01; Lemma: bravery; Antonyms: []; Word Forms: []
Synset: courage.n.01; Lemma: braveness; Antonyms: []; Word Forms: [Lemma(‘brave.a.01.brave’), Lemma(‘audacious.s.01.brave’)]
Synset: fearlessness.n.01; Lemma: fearlessness; Antonyms: [Lemma(‘fear.n.01.fear’)]; Word Forms: [Lemma(‘audacious.s.01.fearless’), Lemma(‘unafraid.a.01.fearless’)]
Synset: fearlessness.n.01; Lemma: bravery; Antonyms: []; Word Forms: []
Собираем всё вместе
Следующий код создаёт список синонимов, антонимов и словоформ для каждой характеристики факультетов. Для полноты анализа некоторые из слов могут быть записаны неправильно.
Характеристики Гриффиндора: [‘bold’, ‘bolder’, ‘boldest’, ‘boldly’, ‘boldness’, ‘brass’, ‘brassier’, ‘brassiest’, ‘brassily’, ‘brassiness’, ‘brassy’, ‘brave’, ‘bravely’, ‘braveness’, ‘braver’, ‘bravery’, ‘bravest’, ‘cheek’, ‘cheekier’, ‘cheekiest’, ‘cheekily’, ‘cheekiness’, ‘cheeky’, ‘chivalry’, ‘courage’, ‘courageous’, ‘courageouser’, ‘courageousest’, ‘courageously’, ‘courageousness’, ‘daring’, ‘face’, ‘fearless’, ‘fearlesser’, ‘fearlessest’, ‘fearlessly’, ‘fearlessness’, ‘gallantry’, ‘hardihood’, ‘hardiness’, ‘heart’, ‘mettle’, ‘nerve’, ‘nervier’, ‘nerviest’, ‘nervily’, ‘nerviness’, ‘nervy’, ‘politesse’, ‘spunk’, ‘spunkier’, ‘spunkiest’, ‘spunkily’, ‘spunkiness’, ‘spunky’]
Антихарактеристики Гриффиндора: [‘cowardice’, ‘fear’, ‘timid’, ‘timider’, ‘timidest’, ‘timidity’, ‘timidly’, ‘timidness’]
Есть какие-то повторы в словаре черт характера? False
Повторы в словаре антонимов? False
Шаг третий: Распределяем студентов по факультетам
Пришло время распределить студентов по факультетам! Наш алгоритм классификации будет работать следующим образом:
Похоже, функция работает. Применим её к нашим данным и посмотрим, что получится!
Совпадение: 0.2553191489361702
Доля ничьих: 0.32978723404255317
Хм. Мы ожидали других результатов. Давайте выясним, почему Волан-де-Морт попал в Хаффлпафф.
Интересно отметить, что в разделе «Личность и черты характера» Волан-де-Морта, самом длинном среди всех студентов, со словарями совпало лишь 31 слово. Это означает, что по другим студентам, вероятно, было гораздо больше совпадений. То есть мы принимаем решение о классификации на основании слишком небольшого количества данных, что и объясняет высокую долю ошибок и большое количество ничьих.
Выводы
Созданный нами классификатор работает не слишком хорошо (немногим точнее, чем простое угадывание), но не забывайте, что наш подход был упрощённым. Современные спам-фильтры очень сложны и не классифицируют лишь на основании наличия конкретных слово. Так что наш алгоритм можно улучшить так, чтобы он учитывал больше информации. Вот небольшой список идей:
What is this kind of assignment in Python called? a = b = True
I know about tuple unpacking but what is this assignment called where you have multiple equals signs on a single line? a la a = b = True
It always trips me up a bit especially when the RHS is mutable, but I’m having real trouble finding the right keywords to search for in the docs.
4 Answers 4
It’s a chain of assignments and the term used to describe it is.
— Could I get a drumroll please?
Chained Assignment.
I just gave it a quite google run and found that there isn’t that much to read on the topic, probably since most people find it very straight-forward to use (and only the true geeks would like to know more about the topic).
In the previous expression the order of evaluation can be viewed as starting at the right-most = and then working towards the left, which would be equivalent of writing:
The above order is what most language describe an assignment-chain, but python does it differently. In python the expression is evaluated as this below equivalent, though it won’t result in any other result than what is previously described.
Further reading available here on stackoverflow:
@refp’s answer is further supported with this output using the dis (disassembly) module:
The RHS is retrieved and duplicated, then stored into the destination variables left-to-right (try this yourself with e = f = g = h = x ).
From the documentation, 7.2. Assignment statements, g and h being two target lists, x being the expression list:
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
OK, «chained assignment» was the search term I was after, but after a bit more digging I think it’s not strictly correct. but it is easier to search for than «a special case of the assignment statement».
In Python, assignment statements do not return a value. Chained assignment (or more precisely, code that looks like chained assignment statements) is recognized and supported as a special case of the assignment statement.
Трюки Pandas от RealPython
К старту флагманского курса по Data Science делимся сокращённым переводом из блога RealPython о трюках с Pandas, материал начинается с конфигурирования запуска библиотеки и заканчиваются примерами работы с операторами и их приоритетом. Затрагивается тема экономии памяти, сжатие фреймов, интроспекция GroupBy через итерацию и другие темы. Подробности, как всегда, под катом.
1. Параметры запуска интерпретатора
Запустив сеанс интерпретатора, вы увидите, что сценарий запуска выполнен и Pandas автоматически импортируется с вашим набором опций:
Воспользуемся данными abalone в репозитории машинного обучения UCI, чтобы продемонстрировать заданное в файле запуска форматирование. Сократим данные до 14 строк с точностью до 4 цифр для чисел с плавающей точкой:
Позже вы увидите этот набор данных и в других примерах.
2. Игрушечные cтруктуры данных с помощью модуля тестирования Pandas
В модуле Pandas testing скрыт ряд удобных функций для быстрого построения квазиреалистичных Series и фреймов данных:
Их около 30, полный список можно увидеть, вызвав dir() на объекте модуля. Вот несколько вариантов:
Они полезны для бенчмаркинга, тестирования утверждений и экспериментов с не очень хорошо знакомыми методами Pandas.
3. Используйте преимущества методов доступа
Возможно, вы слышали о термине акcессор, который чем-то напоминает геттер (хотя геттеры и сеттеры используются в Python нечасто). В нашей статье будем называть аксессором свойство, которое служит интерфейсом для дополнительных методов. В Series [на момент написания оригинальной статьи] их три, сегодня их 4:
Да, приведённое выше определение многозначно, поэтому до обсуждения внутреннего устройства посмотрим на примеры.
.cat — для категориальных данных;
.str — для строковых (объектных) данных;
.dt — для данных, подобных времени.
4. Создание индекса времени даты из столбцов компонентов
Наконец, вы можете отказаться от старых отдельных столбцов и преобразовать их в Series:
Интуитивно суть передачи фрейма данных в том, что DataFrame похож на словарь Python, где имена столбцов — это ключи, а отдельные столбцы (Series) — значения словаря. Поэтому pd.to_datetime (df[datecols].to_dict (orient=’list’)) здесь также будет работать.
5. Использование категориальных данных для экономии времени и места
А что если бы мы могли взять перечисленные выше уникальные цвета и отобразить каждый из них в занимающее меньше места целое число? Наивная реализация:
Другой способ сделать то же самое в Pandas — pd.factorize (colors) :
Так или иначе объект кодируется как перечислимый тип (категориальная переменная).
«Использование памяти Categorical пропорционально количеству категорий плюс длина данных. Напротив, object dtype — это константа, умноженная на длину данных» (Источник).
В colors выше есть соотношение двух значений на каждое уникальное значение, то есть на категорию:
Экономия памяти от преобразования в Categorical хороша, но невелика:
Но, если у вас будет, например, много демографических данных, где мало уникальных значений, объём требуемой памяти уменьшится в 10 раз:
Можно воспроизвести что-то похожее на пример выше, который делался вручную:
Всё, что вам нужно сделать, чтобы в точности повторить предыдущий ручной вывод, — это изменить порядок кодов:
Обратите внимание, что dtype — это int8 NumPy, 8-битное знаковое целое, которое может принимать значения от −127 до 128. Для представления значения в памяти требуется только один байт. 64-битные знаковые int были бы излишеством с точки зрения потребления памяти. Грубый пример привёл к данным int64 по умолчанию, тогда как Pandas достаточно умна, чтобы привести категориальные данные к минимально возможному числовому dtype.
6. Интроспекция объектов Groupby через итерацию
При вызове df.groupby (‘x’) результирующие объекты Pandas groupby могут быть немного непрозрачными. Этот объект инстанцируется лениво и сам по себе не имеет никакого осмысленного представления. Продемонстрируем это на наборе данных abalone из первого примера:
7. Используйте этот трюк с отображением для бининга
Представьте: есть Series и соответствующая «таблица сопоставления», где каждое значение принадлежит к многочленной группе или вообще не принадлежит ни одной группе:
Другими словами, вам нужно сопоставить countries со следующим результатом:
Код значительно быстрее, чем вложенный цикл Python по группам для каждой страны:
Задача — сопоставить каждую группу в groups целому числу. Однако Series.map() не распознаёт ‘ab’ — ему нужна разбитая версия, где каждый символ из каждой группы отображён на целое число. Это делается охватом словаря:
Этот словарь может передаваться в s.map() для сопоставления или «перевода» его значений в соответствующие индексы групп.
8. Загрузка данных из буфера обмена
Это позволяет копировать структурированный текст непосредственно в DataFrame или Series. В Excel данные будут выглядеть примерно так:
Его текстовое представление может выглядеть так:
Просто выделите и скопируйте текст выше и вызовите pd.read_clipboard() :
9. Запись объектов Pandas в сжатый формат
Этот короткий пример завершает список. Начиная с версии Pandas 0.21.0 вы можете записывать объекты Pandas непосредственно для сжатия gzip, bz2, zip или xz, а не хранить несжатый файл в памяти и преобразовывать его. Вот пример, использующий данные abalone из первого трюка:
Коэффициент разницы в размерах равен 11,6:
Data Science — это не только статистика, но и написание кода, который с учётом работы с большими данными должен быть эффективным. В этом одна из причин высокой зарплаты специалиста в науке о данных, стать которым мы можем помочь вам на нашем курсе. Также вы можете узнать, как начать карьеру аналитика или инженера данных, начать с нуля или прокачаться в других направлениях, например, в Fullstack-разработке на Python:
Data Science и Machine Learning