2016-08-20 29 views
17

Jestem nowy pand i próbuje dowiedzieć się, jak dodać kilka kolumn do pandy jednocześnie. Każda pomoc tutaj jest doceniana. Idealnie chciałabym zrobić to w jednym kroku zamiast wielu powtarzających się kroków ...Dodawanie wielu kolumn pandy jednocześnie

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... 

Odpowiedz

21

Spodziewałam się, że twoja składnia również zadziała. Problem pojawia się, ponieważ podczas tworzenia nowych kolumn ze składnią lista_kolumn (df[[new1, new2]] = ...), pandy wymaga, aby prawa strona być DataFrame (należy pamiętać, że w rzeczywistości nie ma znaczenia, czy kolumny DataFrame mają takie same nazwy jak kolumny, które tworzysz).

składni działa dobrze dla przypisywania wartości skalarnych do istniejącego kolumn i pandy jest również chętnie przypisujemy wartości skalarnych do nowej kolumny przy użyciu składni pojedynczej kolumny (df[new1] = ...). Rozwiązaniem jest albo zamiana tego na kilka pojedynczych kolumn, albo stworzenie odpowiedniej ramki danych po prawej stronie.

Oto kilka sposobów, które będzie praca:

import pandas as pd 
import numpy as np 

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

Następnie jedną z następujących czynności:

(1) Technicznie jest to trzy kroki, ale wygląda na to jeden krok:

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

(2) DataFrame wygodnie rozwija pojedynczy wiersz, aby dopasować go do indeksu, dzięki czemu można to zrobić:

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

(3) to będzie działać dobrze, jeśli się tymczasową ramkę danych z nowymi kolumnami, a następnie połączyć z oryginalnej ramki danych późniejszym:

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) podobny do poprzedniego, lecz stosując join zamiast concat (może być mniej efektywna)

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

(5) to jest bardziej „naturalny” sposób, aby utworzyć nową ramkę danych niż w dwóch poprzednich, ale nowe kolumny, które mają być sortowane alfa betically (przynajmniej 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) Lubię ten wariant @ Zero odpowiedzi na wiele, ale podobnie jak poprzedni, nowe kolumny zawsze będą sortowane alfabetycznie, przynajmniej w początkowych wersjach Pythona :

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

(7) to jest ciekawe (na podstawie https://stackoverflow.com/a/44951376/3830997), ale nie wiem kiedy to będzie warta:

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) W koniec trudno pokonać ten:

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

Uwaga: wiele z tych opcji zostały już ujęte w innych odpowiedzi: 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

Z wykorzystaniem 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 

Niezbyt pewny tego, co chcesz zrobić z [np.nan, 'dogs',3]. Może teraz ustawić je jako wartości domyślne?

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

jeśli był sposób na wykonanie drugiej części w jednym kroku - tak wartości stałe w kolumnach jako przykład. – runningbirds

1

wykorzystanie listowego, pd.DataFrame i 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

Chcę tylko podkreślić, że opcja2 w odpowiedzi @Matthias Frippa za

(2) I niekoniecznie spodziewać DataFrame pracować w ten sposób, ale to nie

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

jest już udokumentowana w Pandy własnej dokumentacji http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

można przekazać listę kolumn na [], aby wybrać kolumny, w tej kolejności. Jeśli w ramce DataFrame nie ma kolumny, zostanie zgłoszony wyjątek. Można również ustawić wiele kolumn w ten sposób. Może się okazać, że jest to przydatne do zastosowania transformacji (w miejscu) do podzbioru kolumn.

+0

Myślę, że jest to dość standardowe dla przydziału wielu kolumn. Częścią, która mnie zaskoczyła, było to, że 'pd.DataFrame ([[np.nan, 'dogs', 3]], index = df.index)' replikuje jeden wiersz, który podano, aby utworzyć całą ramkę danych o tej samej długości co indeks. –

4

Można użyć assign z dyktowaniem nazw kolumn i wartości.

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 
Powiązane problemy