DataFrames: перебирая заданные значения для создания нескольких логических столбцов? - PullRequest
1 голос
/ 27 апреля 2020

Столбец term хранит набор из нескольких строк (из фиксированного набора ~ 1000 строк) .

df = pd.DataFrame([[{'city', 'mouse'}], 
                   [{'mouse'}], 
                   [{'blue'}]], 
                  columns=['terms'])

Out[1]
           terms
0  {mouse, city}
1        {mouse}
2         {blue}

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

           terms  has_mouse  has_city  has_blue
0  {mouse, city}          1         1         0
1        {mouse}          1         0         0
2         {blue}          0         0         1

Я попробовал это:

def count_terms_in_row(row):
    for term in row['terms']:
        row['has_{}'.format(term)] = 1

df.apply(count_terms_in_row, axis=1)

Однако это не сработало, как планировалось. Какой правильный подход здесь?

Ответы [ 3 ]

2 голосов
/ 27 апреля 2020

Вы можете сделать следующее:

import pandas as pd
import numpy as np

df = pd.DataFrame([[{'city', 'mouse'}], 
                   [{'mouse'}], 
                   [{'blue'}]], 
                  columns=['terms'])


all_terms = set()
for idx, data in df.iterrows():
  all_terms = all_terms.union(data["terms"])

# find out all new columns
new_columns = []
term2idx = {}
for idx, term in enumerate(all_terms):
  new_columns.append("has_term_{}".format(term))
  term2idx[term] = idx

# add new data per new column
new_data = []
for idx, data in df.iterrows():
  _row = [0] * len(new_columns)
  for term in data["terms"]:
    _row[term2idx[term]] = 1
  new_data.append(_row)

# add new data to existing DataFrame
new_data = np.asarray(new_data)
for idx in range(len(new_columns)):
  df[new_columns[idx]] = new_data[:,idx]

print(df.head())

В результате:

    terms   has_term_city   has_term_blue   has_term_mouse
0   {city, mouse}   1   0   1
1   {mouse} 0   0   1
2   {blue}  0   1   
1 голос
/ 27 апреля 2020

Это по существу get_dummies:

df.join(pd.get_dummies(df.terms.apply(list).explode())
          .sum(level=0)
          .add_prefix('has_')
       ) 

Вывод:

           terms  has_blue  has_city  has_mouse
0  {mouse, city}         0         1          1
1        {mouse}         0         0          1
2         {blue}         1         0          0
0 голосов
/ 27 апреля 2020

Вы можете попробовать это:

df['count'] = df['terms'].str.len()
print(df)

           terms  count
0  {mouse, city}      2
1        {mouse}      1
2         {blue}      1
...