2016-07-29 2 views
1

У меня есть DataFrame, который я взял из баскетбольной ссылки с именами игроков. Ниже приведен код, как я построил DataFrame. Он имеет 5 столбцов имен игроков, но каждое имя также имеет позицию игрока.Почему столбец из панд DataFrame не работает в этом цикле?

url = "http://www.basketball-reference.com/awards/all_league.html" 
dframe_list = pd.io.html.read_html(url) 
df = dframe_list[0] 
df.drop(df.columns[[0,1,2]], inplace=True, axis=1) 
column_names = ['name1', 'name2', 'name3', 'name4', 'name5'] 
df.columns = column_names 
df = df[df.name1.notnull()] 

Я пытаюсь отделить положение. Для этого я планировал сделать DataFrame для каждого столбца Имя:

name1 = pd.DataFrame(df.name1.str.split().tolist()).ix[:,0:1] 
name1[0] = name1[0] + " " + name1[1] 
name1.drop(name1.columns[[1]], inplace=True, axis=1) 

Поскольку у меня есть пять столбцов, я думал, что я хотел бы сделать это с петлей

column_names = ['name1', 'name2', 'name3', 'name4', 'name5'] 
for column in column_names: 
    column = pd.DataFrame(df.column.str.split().tolist()).ix[:,0:1] 
    column[0] = column[0] + " " + column[1] 
    column.drop(column.columns[[1]], inplace=True, axis=1) 
    column.columns = column 

И тогда я присоединяюсь ко всем эти DataFrames обратно вместе.

df_NBA = [name1, name2, name3, name4, name5] 
df_NBA = pd.concat(df_NBA, axis=1) 

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

AttributeError: 'DataFrame' object has no attribute 'column' 

Похоже, что часть петли df.column.str вызывают некоторые проблемы ? Я просмотрел список со столбцом с надписью (я до сих пор не понимаю, почему иногда я скопирую столбец DataFrame, а иногда это .column, но это большая проблема) и другие случайные вещи.

Когда я пытаюсь @ предложение BrenBarn в

df.apply(lambda c: c.str[:-2]) 

следующие всплывает в Jupyter записной книжке:

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame 

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy 
    if __name__ == '__main__': 

Глядя на DataFrame, ничего фактически не изменилось, и если я понимаю документацию правильно это метод создает копию DataFrame с изменениями, но это временная копия, которая впоследствии выкидывается, поэтому фактический DataFrame не изменяется.

+0

Вы говорите, что это также не работает, если вы выполняете 'df [column]'? – BrenBarn

+2

'df.column' соответствует' df ['column'] ', а не' df [column] '. Поэтому, когда столбец является переменной, вы не можете использовать его так. – ayhan

+0

@BrenBarn, да, это не работает, если я использую 'df [column]', 'df ['column']', я думаю, это то, о чем говорит @ayhan. Так есть ответ? – vino88

ответ

2

Если положение метки всегда только один символ, простое решение заключается в следующем:

>>> df.apply(lambda c: c.str[:-2]) 
      name1   name2 
0  Marc Gasol Lebron James 
1  Pau Gasol Kevin Durant 
2 Dwight Howard Kyrie Irving 

атрибут из серии str позволяет выполнять операции со строками, в том числе индексации, так что это просто обрезает последние два символа от каждого значения.

Что касается вашего вопроса о df.column, этот вопрос более общий, чем панды. Эти две вещи не то же самое:

# works 
obj.attr 

# doesn't work 
attrName = 'attr' 
obj.attrName 

Вы не можете использовать точечную нотацию, когда вы хотите получить доступ к атрибуту, имя которого хранится в переменной. В общем случае вы можете использовать функцию getattr. Тем не менее, pandas предоставляет запись в скобках для доступа к столбцу, указав имя как строку (а не идентификатор исходного кода). Таким образом, эти два эквивалентны:

df.some_column 

columnName = "some_column" 
df[columnName] 

В вашем примере, изменив ссылку на df.column в df[column] должны решить эту проблему. Однако, как я уже упоминал в комментарии, ваш код также имеет другие проблемы.Что касается решения поставленной задачи, то метод строковой индексации, который я показал в начале моего ответа, намного проще.

+0

Ahhh, спасибо! – vino88

+0

Благодарим за решение, к сожалению, когда я пытаюсь это сделать на фактическом DataFrame, это ничего не меняет. В ноутбуке Jupyter появляется красное поле и указывается, что «значение пытается установить на копии среза из DataFrame» и говорит, что это вызывает ошибку SettingWithCopy. В документации указывается, что этот метод может возвращать копию временного представления DataFrame, которое впоследствии будет выбрано, поэтому оно не будет работать. – vino88

+1

@ vino88: Тогда, пожалуйста, отредактируйте свой вопрос, включив в него самодостаточный пример, демонстрирующий проблему. (Или задайте отдельный вопрос, если ваш новый вопрос действительно об этом новом способе его выполнения и не связан с кодом, который вы разместили здесь.) – BrenBarn

Смежные вопросы