Вопросы о пандах: расширение многозначной колонны, инвертирование и группировка

Я изучал панды, чтобы сделать некоторые простые вычисления в области НЛП и интеллектуального анализа текста, но я не мог понять, как это сделать.

Предположим, у меня есть следующий фрейм данных, связанный с именами людей и их полом:

import pandas people = {'name': ['John Doe', 'Mary Poppins', 'Jane Doe', 'John Cusack'], 'gender': ['M', 'F', 'F', 'M']} df = pandas.DataFrame(people) 

Для всех строк я хочу:

  1. определить имя
  2. определить список 3-черепиц (последовательности из 3 букв, содержащихся в слове), полученные от имени человека
  3. определите, для каждой гальки, сколько мужчин и женщин содержало эту гальку на их именах.

Цель состоит в том, чтобы использовать это как набор данных для обучения классификатора, который может определить, является ли данное имя, вероятно, мужским или женским именем.

Первые две операции довольно просты:

 def shingles(word, n = 3): return [word[i:i + n] for i in range(len(word) - n + 1)] df['firstname'] = df.name.map(lambda x : x.split()[0]) df['shingles'] = df.firstname.map(shingles) 

результат:

 > print df gender name firstname shingles 0 M John Doe John ['joh', 'ohn'] 1 F Mary Poppins Mary ['mar', 'ary'] 2 F Jane Doe Jane ['jan', 'ane'] 3 M John Cusack John ['joh', 'ohn'] 

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

  gender shingle 0 M joh 1 M ohn 2 F mar 3 F ary (...) 

И тогда я мог бы группироваться по гальке и полу. В идеале результатом будет:

  shingle num_males num_females 0 joh 2 0 1 ohn 2 0 2 mar 0 1 3 ary 0 1 (...) 

Есть ли простой способ расширить многозначные shingles столбцов таким образом, что каждая строка создает несколько строк, по одному для каждого значения, найденного в списке черепицы?

Кроме того, если я groupby столбцовую shingle , насколько легко создавать разные столбцы с подсчетом для каждого возможного значения столбца?


Мне удалось понять вторую часть. В качестве примера, чтобы рассчитать, сколько мужчин и женщин для каждого имени:

  def countMaleFemale(df): return pandas.Series({'males': df.gender[df.gender == 'M'].count(), 'females': df.gender[df.gender == 'F'].count()}) grouped = df.groupby('first name') 

А потом:

print grouped.apply (countMaleFemale)

  females males first name Jane 1 0 John 0 2 Mary 1 0 

2 Solutions collect form web for “Вопросы о пандах: расширение многозначной колонны, инвертирование и группировка”

Этот метод должен достаточно хорошо обобщаться:

 In [100]: df Out[100]: gender name firstname shingles 0 M John Doe John [Joh, ohn] 1 F Mary Poppins Mary [Mar, ary] 2 F Jane Doe Jane [Jan, ane] 3 M John Cusack John [Joh, ohn] 

Сначала создайте «расширенную» серию, где каждая запись представляет собой галерею. Здесь индекс серии представляет собой мультииндекс, где первый уровень представляет положение гальки, а второй уровень представляет собой индекс исходного DF:

 In [103]: s = df.shingles.apply(lambda x: pandas.Series(x)).unstack(); Out[103]: 0 0 Joh 1 Mar 2 Jan 3 Joh 1 0 ohn 1 ary 2 ane 3 ohn 

Затем мы можем присоединиться к созданной серии в исходный фрейм данных. Вы должны сбросить индекс, понизив уровень положения гальки. Полученная серия имеет исходный индекс и запись для каждой гальки. Объединение этого в исходный dataframe дает:

 In [106]: df2 = df.join(pandas.DataFrame(s.reset_index(level=0, drop=True))); df2 Out[106]: gender name firstname shingles 0 0 M John Doe John [Joh, ohn] Joh 0 M John Doe John [Joh, ohn] ohn 1 F Mary Poppins Mary [Mar, ary] Mar 1 F Mary Poppins Mary [Mar, ary] ary 2 F Jane Doe Jane [Jan, ane] Jan 2 F Jane Doe Jane [Jan, ane] ane 3 M John Cusack John [Joh, ohn] Joh 3 M John Cusack John [Joh, ohn] ohn 

Наконец, вы можете выполнить свою групповую операцию в поле «Пол», отложить возвращенную строку и заполнить NaN нулями:

 In [124]: df2.groupby(0, sort=False)['gender'].value_counts().unstack().fillna(0) Out[124]: FM 0 Joh 0 2 ohn 0 2 Mar 1 0 ary 1 0 Jan 1 0 ane 1 0 

Возможно, было бы легче создать расширенную версию во время создания shingles . Этот вопрос показывает, как вы можете использовать groupby для такого рода расширения. Вот пример того, что вы можете сделать после создания столбца «Имя»:

 def shingles(table, n = 3): word = table['first name'].irow(0) shingles = [word[i:i + n] for i in range(len(word) - n + 1)] cols = {col: table[col].irow(0) for col in table.columns} cols['shingle'] = shingles return pandas.DataFrame(cols) >>> df.groupby('name', group_keys=False).apply(shingles) first name gender name shingle 0 Jane F Jane Doe Jan 1 Jane F Jane Doe ane 0 John M John Cusack Joh 1 John M John Cusack ohn 0 John M John Doe Joh 1 John M John Doe ohn 0 Mary F Mary Poppins Mar 1 Mary F Mary Poppins ary 

(Я сгруппирован по имени здесь, а не по имени, на всякий случай, если есть повторяющиеся имена, но предполагает, что полное имя уникально.)

Оттуда вы сможете сгруппировать и подсчитать все, что захотите.

  • Почему мои панды roll () работают (apply), когда серия содержит коллекции?
  • Pandas scatter_matrix - определение категориальных переменных
  • Добавление списка или серии в pandas DataFrame в виде строки?
  • Python pandas datareader не работает
  • Pandas выравнивает несколько фреймов данных с индексом TimeStamp
  • матрицы не выровнены сообщение об ошибке
  • Pandas обновляет сразу несколько столбцов
  • Как заполнить данные Nan с пустым списком в pandas?
  • Python - лучший язык программирования в мире.