2016-08-20 4 views
17

Я новичок в pandas и пытаюсь понять, как добавить несколько столбцов в pandas одновременно. Любая помощь здесь ценится. В идеале я хотел бы сделать это за один шаг, а не несколько повторяющихся шагов ...Добавление нескольких столбцов в pandas одновременно

import pandas as pd 

df = {'col_1': [0, 1, 2, 3], 
     'col_2': [4, 5, 6, 7]} 
df = pd.DataFrame(df) 

df[[ 'column_new_1', 'column_new_2','column_new_3']] = [np.nan, 'dogs',3] #thought this would work here... 

ответ

21

Я бы ожидал, что ваш синтаксис тоже будет работать. Проблема возникает из-за того, что при создании новых столбцов с синтаксисом списка столбцов (df[[new1, new2]] = ...), панды требуют, чтобы правая часть была DataFrame (обратите внимание, что на самом деле не имеет значения, имеют ли столбцы DataFrame те же имена, что и столбцы, которые вы создаете).

Ваш синтаксис работает для присвоения скалярных значений существующих столбцов, и панды также рады назначить скалярные значения в новый столбец, используя синтаксис одного столбца (df[new1] = ...). Таким образом, решение состоит в том, чтобы преобразовать это в несколько назначений с одним столбцом или создать подходящий DataFrame для правой стороны.

Вот несколько подходов, которые будут работы:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({ 
    'col_1': [0, 1, 2, 3], 
    'col_2': [4, 5, 6, 7] 
}) 

Тогда один из следующих действий:

(1) Технически это три шага, но это выглядит как один шаг:

df['column_new_1'], df['column_new_2'], df['column_new_3'] = [np.nan, 'dogs', 3] 

(2) DataFrame удобно расширяет одну строку в соответствии с индексом, так что вы можете сделать это:

df[['column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame([[np.nan, 'dogs', 3]], index=df.index) 

(3) Это будет работать хорошо, если вы сделаете временный фрейм данных с новыми столбцами, то в сочетании с оригинальным кадром данных позже:

df = pd.concat(
    [ 
     df, 
     pd.DataFrame(
      [[np.nan, 'dogs', 3]], 
      index=df.index, 
      columns=['column_new_1', 'column_new_2', 'column_new_3'] 
     ) 
    ], axis=1 
) 

(4) Аналогично предыдущему, но используя join вместо concat (может быть менее эффективным):

df = df.join(pd.DataFrame(
    [[np.nan, 'dogs', 3]], 
    index=df.index, 
    columns=['column_new_1', 'column_new_2', 'column_new_3'] 
)) 

(5) Это более «естественный» способ создать новый кадр данных, чем предыдущие два, но новые столбцы будут отсортированы lphabetically (по крайней мере before Python 3.6 or 3.7):

df = df.join(pd.DataFrame(
    { 
     'column_new_1': np.nan, 
     'column_new_2': 'dogs', 
     'column_new_3': 3 
    }, index=df.index 
)) 

(6) Мне нравится этот вариант на @ обнулить Ответим много, но, как и предыдущую, новые столбцы всегда будут отсортированы в алфавитном порядке, по крайней мере, с ранними версиями Python :

df = df.assign(column_new_1=np.nan, column_new_2='dogs', column_new_3=3) 

(7) Это интересно (основано на https://stackoverflow.com/a/44951376/3830997), но я не знаю, когда это будет стоит свеч:

new_cols = ['column_new_1', 'column_new_2', 'column_new_3'] 
new_vals = [np.nan, 'dogs', 3] 
df = df.reindex(columns=df.columns.tolist() + new_cols) # add empty cols 
df[new_cols] = new_vals # multi-column assignment works for existing cols 

(8) В конец это трудно превзойти это:

df['column_new_1'] = np.nan 
df['column_new_2'] = 'dogs' 
df['column_new_3'] = 3 

Примечание: многие из этих вариантов уже охвачены в других ответов: Add multiple columns to DataFrame and set them equal to an existing column, Is it possible to add several columns at once to a pandas DataFrame?, Pandas: Add multiple empty columns to DataFrame

2

С использованием concat:

In [128]: df 
Out[128]: 
    col_1 col_2 
0  0  4 
1  1  5 
2  2  6 
3  3  7 

In [129]: pd.concat([df, pd.DataFrame(columns = [ 'column_new_1', 'column_new_2','column_new_3'])]) 
Out[129]: 
    col_1 col_2 column_new_1 column_new_2 column_new_3 
0 0.0 4.0   NaN   NaN   NaN 
1 1.0 5.0   NaN   NaN   NaN 
2 2.0 6.0   NaN   NaN   NaN 
3 3.0 7.0   NaN   NaN   NaN 

Не очень уверен, что вы хотели сделать с [np.nan, 'dogs',3]. Может быть, теперь задайте их как значения по умолчанию?

In [142]: df1 = pd.concat([df, pd.DataFrame(columns = [ 'column_new_1', 'column_new_2','column_new_3'])]) 
In [143]: df1[[ 'column_new_1', 'column_new_2','column_new_3']] = [np.nan, 'dogs', 3] 

In [144]: df1 
Out[144]: 
    col_1 col_2 column_new_1 column_new_2 column_new_3 
0 0.0 4.0   NaN   dogs    3 
1 1.0 5.0   NaN   dogs    3 
2 2.0 6.0   NaN   dogs    3 
3 3.0 7.0   NaN   dogs    3 
+0

если был способ сделать вашу вторую часть за один шаг - в качестве примера приведены постоянные значения в столбцах. – runningbirds

1

использование списка понимания, pd.DataFrame и pd.concat

pd.concat(
    [ 
     df, 
     pd.DataFrame(
      [[np.nan, 'dogs', 3] for _ in range(df.shape[0])], 
      df.index, ['column_new_1', 'column_new_2','column_new_3'] 
     ) 
    ], axis=1) 

enter image description here

0

Просто хочу указать, что option2 в ответ @Matthias Фриппа

(2) Я бы не обязательно ожидать DataFrame работать таким образом, но это не

ДФ [[ 'column_new_1', 'column_new_2', 'column_new_3']] = pd.DataFrame ([[np.nan, 'dogs, 3]], index = df.индекс)

уже задокументированы в собственной документации панд http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

Вы можете передать список столбцов в [], чтобы выбрать столбцы в указанном порядке. Если столбец не содержится в DataFrame, будет создано исключение. Несколько столбцов также могут быть установлены таким образом. Вы можете найти это полезным для применения преобразования (на месте) к подмножеству столбцов.

+0

Я думаю, что это довольно стандартный для назначения нескольких столбцов. Часть, которая меня удивила, заключалась в том, что 'pd.DataFrame ([[np.nan, 'dogs, 3]], index = df.index)' реплицирует одну строку, которую он задает, для создания целого кадра данных той же длины, что и индекс. –

4

Вы можете использовать assign с указанием имен и значений столбцов.

In [1069]: df.assign(**{'col_new_1': np.nan, 'col2_new_2': 'dogs', 'col3_new_3': 3}) 
Out[1069]: 
    col_1 col_2 col2_new_2 col3_new_3 col_new_1 
0  0  4  dogs   3  NaN 
1  1  5  dogs   3  NaN 
2  2  6  dogs   3  NaN 
3  3  7  dogs   3  NaN 
Смежные вопросы