Создание колонны панд

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

from numpy.random import randn
import pandas as pd

df = pd.DataFrame({'a':range(0,10,2), 'c':range(0,1000,200)},
columns=list('ac'))
df['b'] = 10*df.a
df

дает следующий результат:

введите описание изображения здесь

Тем не менее, если бы я попытался создать столбец b, заменив его следующей строкой, сообщения об ошибке не было бы, но в кадре данных df остались только столбцы a и c.

df.b = 10*df.a   ### rather than the previous df['b'] = 10*df.a ###

Что сделали панды и почему моя команда неверна?

3 ответа

Что вы сделали, так это добавили атрибут b на ваш df:

In [70]:
df.b = 10*df.a 
df.b

Out[70]:
0     0
1    20
2    40
3    60
4    80
Name: a, dtype: int32

но мы видим, что новый столбец не был добавлен:

In [73]:    
df.columns

Out[73]:
Index(['a', 'c'], dtype='object')

а это значит, что мы получаем KeyError если бы мы попытались df['b']Чтобы избежать этой неоднозначности, вы всегда должны использовать квадратные скобки при назначении.

например, если у вас был столбец с именем index или же sum или же max затем делать df.index вернул бы индекс, а не столбец индекса, и аналогично df.sum а также df.max испортил бы те методы df.

Я настоятельно советую всегда использовать квадратные скобки, это позволяет избежать двусмысленности, а последний ipython может разрешать имена столбцов с помощью квадратных скобок. Также полезно думать о фрейме данных как о серии, в которой имеет смысл использовать квадратные скобки для назначения и возврата столбца.

Всегда используйте квадратные скобки для назначения столбцов

Точечная запись удобна для доступа к столбцам в кадре данных. Если они конфликтуют с существующими свойствами (например, если у вас есть столбец с именем "max"), вам нужно использовать квадратные скобки для доступа к этому столбцу, например df['max'], Вам также нужно использовать квадратные скобки, когда имя столбца содержит пробелы, например df['max value'],

DataFrame - это просто объект, имеющий обычные свойства и методы. Если вы используете точечную запись для назначения, вы создаете свойство или метод для объекта dataframe. Так df.val = 2 назначит df с собственностью val это имеет значение два. Это очень отличается от df['val'] = 2 который создает новый столбец в кадре данных и присваивает каждому элементу в этом столбце значение два.

Чтобы быть в безопасности, использование квадратных скобок всегда даст правильный результат.

Как в стороне, ваш columns=list('ac')) ничего не делает, так как вы просто создаете переменную с именем columns это никогда не используется. Вы могли иметь в виду df.columns = list('ac'), но вы уже назначили их при создании фрейма данных, поэтому я не уверен, какова цель этой строки кода. И помните, что словари неупорядочены, так что pd.DataFrame({'a': [...], 'b': [...]}) потенциально может вернуть фрейм данных со столбцами ['b', 'a']. Если бы это было так, то присвоение имен столбцов может потенциально смешивать заголовки столбцов.

Проблема связана с тем, как свойства обрабатываются в Python. В python нет ограничений на установку новых свойств для класса, так что, например, вы можете сделать что-то вроде

df.myspecialstuff = ["dog", "cat", 5]

Поэтому, когда вы делаете назначение, как

df.b = 10*df.a

Однозначно, хотите ли вы добавить свойство или новый столбец, и свойство установлено. Самый простой способ на самом деле увидеть, что происходит с этим, - это использовать pdb и пройтись по коду

import pdb
x = df.a
pdb.run("df.a1 = x")

Это вступит в __setattr__() в то время как pdb.run("df['a2'] = x") вступит в __setitem__()

Другие вопросы по тегам