Добавление нового столбца или строки как pd.Series

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Я пытаюсь добавить один столбец и одну строку с помощью pd.Series объекта. Вот что у меня есть на данный момент:

 import pandas as pd
df = pd.DataFrame([
    {"Title": "Titanic",    "ReleaseYear": 1997, "Director": "James Cameron"},
    {"Title": "Spider-Man", "ReleaseYear": 2002, "Director": "Sam Raimi"}
])

# Add a new row
new_movie_row = pd.Series(['Jurassic Park', 1993, 'Steven Spielberg'])
df.loc[2] = new_row

# Add a new column
new_keyword_column = pd.Series(['Boat', 'Spider', 'Dinosaur'])
df['Keyword'] = new_keyword_column
df
  

Кажется, что это добавляет столбец нормально, однако строка дает мне все NaN :

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

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

Ответ №1:

Pandas пытается выровнять на основе имен индексов / столбцов, это называется Data Alignment , мы можем использовать .tolist здесь.

 df.loc[2] = new_movie_row.tolist()
df
           Title  ReleaseYear          Director
0        Titanic         1997     James Cameron
1     Spider-Man         2002         Sam Raimi
2  Jurassic Park         1993  Steven Spielberg
  

То же самое относится и к добавлению столбцов

 new_keyword_column = pd.Series(['Boat', 'Spider', 'Dinosaur'],index=[4,5,6])  # Notice the Index is 4, 5, 6.

df['new'] = new_keyword_column
df
           Title  ReleaseYear          Director  new
0        Titanic         1997     James Cameron  NaN
1     Spider-Man         2002         Sam Raimi  NaN
2  Jurassic Park         1993  Steven Spielberg  NaN
  

Поскольку индексы не выравниваются, вы получаете все NaN , для противодействия этому вы можете использовать .tolist()

 df['new'] = new_keyword_column.tolist()
df
           Title  ReleaseYear          Director       new
0        Titanic         1997     James Cameron      Boat
1     Spider-Man         2002         Sam Raimi    Spider
2  Jurassic Park         1993  Steven Spielberg  Dinosaur
  

Комментарии:

1. спасибо, не могли бы вы, пожалуйста, объяснить, как использование tolist() решает проблему?

2. Спасибо за разъяснение — как Pandas пытается выровнять строку по умолчанию? С тремя значениями и тремя столбцами я удивлен, что Pandas не «автоматически выравнивает» это самостоятельно?

3. Не понял, вы можете, пожалуйста, уточнить? Вы можете прочитать более подробную информацию о Data alignment здесь.

Ответ №2:

Если хотите добавить новую строку или столбец, используется выравнивание (это означает, что pandas пытается сопоставить значения индекса серии и столбцы / строки фрейма данных, если совпадение отсутствует, получите NaN s для отсутствия совпадающих значений):

Ваш подход хорош, необходимо только установить те же значения индекса Series для новой строки:

 # Add a new row
new_movie_row = pd.Series(['Jurassic Park', 1993, 'Steven Spielberg'], index=df.columns)
df.loc[2] = new_movie_row
  

Если значения индекса по умолчанию в DataFrame, то индекс по умолчанию тот же, но для общих данных тоже необходим.

 # Add a new column
new_keyword_column = pd.Series(['Boat', 'Spider', 'Dinosaur'], index=df.index)
df['Keyword'] = new_keyword_column

print (df)
           Title  ReleaseYear          Director   Keyword
0        Titanic         1997     James Cameron      Boat
1     Spider-Man         2002         Sam Raimi    Spider
2  Jurassic Park         1993  Steven Spielberg  Dinosaur
  

Но обычно, если нужна новая строка / столбец, можно использовать список или одномерный массив одинаковой длины (или скалярный, если нужны одинаковые значения):

 # Add a new row
df.loc[2] = ['Jurassic Park', 1993, 'Steven Spielberg']

# Add a new column
df['Keyword'] = ['Boat', 'Spider', 'Dinosaur']
  

 # Add a new column with same values
df['same vals'] = 10
  


Почему необходимо использовать Series, а не только списки?

Только если отсутствуют некоторые входные данные, тогда необходимо выровнять по ряду:

 # Add a new row
new_movie_row = pd.Series(['Jurassic Park', 1993], index=['Title','ReleaseYear'])
df.loc[2] = new_movie_row
print (df)
           Title  ReleaseYear       Director
0        Titanic         1997  James Cameron
1     Spider-Man         2002      Sam Raimi
2  Jurassic Park         1993            NaN
  

Или укажите столбцы тоже:

 df.loc[2, ['Title','ReleaseYear']] = ['Jurassic Park', 1993]
  

Если использовать только список, выдается ошибка:

 df.loc[3] = ['Jurassic Park', 1993]
print (df)

>ValueError: cannot set a row with mismatched columns
  

Комментарии:

1. спасибо, не могли бы вы, пожалуйста, объяснить, почему требуется настройка index ? Разве он не знал бы, что столбец длиной три «поместится»?

2. @David542 Установка индекса серии решает эту проблему, потому что pandas пытается выровнять индексы

3. @David542 — да, если длина такая же. Если требуется другая длина Series , ошибка elese.

4. @David542 — добавлено для ответа.

5. @jezrael Справедливое замечание, если использование не той же длины pd.Series с подходящим индексом учитывает это. 1