#python #pandas
#python #pandas
Вопрос:
Краткое раскрытие: я родом из R background и переключаюсь на pandas (работает на python 3.3.3).
Я хотел бы выбрать строки из фрейма данных, используя текст из записи фрейма данных. Это элементарная операция, но я не смог обойти синтаксис.
Например, с помощью этого фрейма данных (извините за разделение строк, но я хочу сделать пример более понятным):
films = pandas.DataFrame({'$title':[ "The Godfather",
"Pulp Fiction",
"The Godfather: Part II",
"Fight Club"],
'$director': [ "Coppola, Francis Ford",
"Tarantino, Quentin",
"Coppola, Francis Ford",
"Fincher, David"]})
Если я хочу выбрать все фильмы, созданные первым режиссером, которым будет «Коппола, Фрэнсис Форд», команда, которую я использую, это:
In [1]: director = films.iloc[[1]]["director"]
In [2]: director
1 Coppola, Francis Ford
Name: director, dtype: object
In [3]: a = films[ films["director"] == director ]
ValueError: Series lengths must match to compare
Если я сделаю это:
In [4]: a = films[ films["director"] == str(director) ]
Я получаю пустой фрейм данных. Что здесь происходит? Похоже, я что-то упускаю.
Комментарии:
1. Как объяснил kermit666, в этом вопросе есть довольно ошибок, и использование точечной нотации сделало вещи намного понятнее.
Ответ №1:
Хорошо, прежде всего, я вижу, что вы допустили пару ошибок стиля / семантики, которые являются общими для преобразований R в Python:
- вам не нужны
$
знаки для имен ваших столбцов, и это фактически упрощает выбор столбцов, поскольку вы можете написатьfilms.director
, если только имя'director'
(оно должно быть действительным идентификатором Python для работы этого синтаксического сахара) - индексация в Python начинается с 0, а не с 1, поэтому вы выбираете 1-го директора как
films.director[0]
Предполагая, что вы удалили $
знаки из своего определения фрейма данных, вы можете выбрать фильмы как:
In [16]: films[films['director'] == films['director'][0]]
Out[16]:
director title
0 Coppola, Francis Ford The Godfather
2 Coppola, Francis Ford The Godfather: Part II
или даже чище, как films[films.director == films.director[0]]
.
Используя исходный фрейм данных, вы можете выполнить свой запрос с:
director = films.iloc[[1]]['$director'][1]
films[films['$director'] == director]
Одна ошибка заключалась в том, что вы сначала определили таблицу с '$director'
помощью, а затем запросили ее в 'director'
качестве имени столбца.
[1]
В конце необходимо, потому что вы индексировали фрейм данных списком [1]
, а не значением 1
, поэтому вы получили обратно серию, как уже заметил CT Zhu. Индексация списка предназначена больше для выбора нескольких произвольных элементов, таких как films.iloc[[1, 3]]
. В вашем случае было бы понятнее написать
director = films.iloc[1]['$director']
Кроме того, обратите внимание, что это все равно получает Тарантино, а не Коппола.
Ответ №2:
Я думаю films[ films["director"] == films.ix[0, 'director' ]]
, этого будет достаточно.
Причина films.iloc[[1]]["director"]
не будет работать, потому что это a Series
, а не a string
.
Если вы хотите использовать iloc
, сделайте: films.iloc[1]["director"]
вместо films.iloc[[1]]["director"]
Также:
In [241]:
str(films.iloc[[1]]["director"])
Out[241]:
'1 Tarantino, QuentinnName: director, dtype: object'
таким образом, films[ films["director"] == str(director) ]
ничего не будет соответствовать и вернет пустой фрейм данных.
Комментарии:
1. Спасибо, я посмотрю на ответ, когда вернусь. Я считаю, что когда iloc [1] не даст мне первый элемент, если я отсортирую фрейм данных.
2. Кроме того, обратите внимание, что индекс in
python
начинается с 0, а не с 1 вR
иmatlab
, ура!