Adăugarea de noi coloane existente DataFrame în Python panda

Am urmatoarele indexate DataFrame cu nume de coloane și rânduri nu - continuă numere:

          a         b         c         d
2  0.671399  0.101208 -0.181532  0.241273
3  0.446172 -0.243316  0.051767  1.577318
5  0.614758  0.075793 -0.451460 -0.012493

Aș dori să adăugați o nouă coloană, 'e', existente cadru de date și nu vreau să schimb nimic în cadru de date (de exemplu, noua coloană are întotdeauna aceeași lungime ca DataFrame).

0   -0.335485
1   -1.166658
2   -0.385571
dtype: float64

Am încercat diferite versiuni ale "se alăture", append, merge, dar nu am primit rezultatul am vrut, numai erori la mai mult. Cum pot adăuga coloana "e", pentru exemplul de mai sus?

Soluția

Utilizare original df1 indici pentru a crea seria:

df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)

Edit 2015 Unii au raportat obtinerea `SettingWithCopyWarning cu acest cod. Cu toate acestea, codul încă rulează perfect cu actualul panda versiune 0.16.1.

>>> sLength = len(df1['a'])
>>> df1
          a         b         c         d
6 -0.269221 -0.026476  0.997517  1.294385
8  0.917438  0.847941  0.034235 -0.448948

>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e
6 -0.269221 -0.026476  0.997517  1.294385  1.757167
8  0.917438  0.847941  0.034235 -0.448948  2.228131

>>> p.version.short_version
'0.16.1'

Anii SettingWithCopyWarning își propune să informeze de un eventual invalid misiune pe o copie a Dataframe. Nu't spune neapărat că ai greșit (se poate declanșa alarme false) dar din 0.13.0 este să știi că acolo sunt mai adecvate metode pentru același scop. Apoi, dacă aveți de avertizare, trebuie doar să urmezi sale recomanda: Încercați să utilizați .loc[row_index,col_indexer] = valoare

>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
          a         b         c         d         e         f
6 -0.269221 -0.026476  0.997517  1.294385  1.757167 -0.050927
8  0.917438  0.847941  0.034235 -0.448948  2.228131  0.006109
>>> 

În fapt, aceasta este în prezent cea mai eficientă metodă ca descrise la panda docs


Edit 2017

După cum este indicat în comentariile și cu @Alexandru, în prezent cea mai bună metodă de a adăuga valorile dintr-o Serie, ca o nouă coloană de DataFrame ar putea fi folosind atribuie:

df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)
Comentarii (27)

Acesta este modul simplu de a adăuga o nouă coloană: df['e'] = e

Comentarii (4)

aș dori să adăugați o nouă coloană, 'e', existente cadru de date și nu se schimbă nimic în cadru de date. (Seria întotdeauna aceeași lungime ca un dataframe.)

Presupun că valorile indicelui în " e " se potrivesc cu cele din df1.

Cel mai simplu mod de a iniția o nouă coloană numită "e", și atribuie valori din seria "e":

df['e'] = e.values

atribuirea (Panda 0.16.0+)

Ca de Panda 0.16.0, puteți utiliza, de asemenea, atribui, care atribuie noi coloane într-un DataFrame și returnează un obiect nou (o copie), cu toate coloanele original în plus față de cele noi.

df1 = df1.assign(e=e.values)

Ca pe acest exemplu (care include, de asemenea, codul sursă al atribuie funcția), puteți include, de asemenea, mai mult de o coloană:

df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
>>> df.assign(mean_a=df.a.mean(), mean_b=df.b.mean())
   a  b  mean_a  mean_b
0  1  3     1.5     3.5
1  2  4     1.5     3.5

În context cu exemplu:

np.random.seed(0)
df1 = pd.DataFrame(np.random.randn(10, 4), columns=['a', 'b', 'c', 'd'])
mask = df1.applymap(lambda x: x >> df1
          a         b         c         d
0  1.764052  0.400157  0.978738  2.240893
2 -0.103219  0.410599  0.144044  1.454274
3  0.761038  0.121675  0.443863  0.333674
7  1.532779  1.469359  0.154947  0.378163
9  1.230291  1.202380 -0.387327 -0.302303

>>> e
0   -1.048553
1   -1.420018
2   -1.706270
3    1.950775
4   -0.509652
dtype: float64

df1 = df1.assign(e=e.values)

>>> df1
          a         b         c         d         e
0  1.764052  0.400157  0.978738  2.240893 -1.048553
2 -0.103219  0.410599  0.144044  1.454274 -1.420018
3  0.761038  0.121675  0.443863  0.333674 -1.706270
7  1.532779  1.469359  0.154947  0.378163  1.950775
9  1.230291  1.202380 -0.387327 -0.302303 -0.509652

Descrierea de această nouă caracteristică atunci când a fost introdus pentru prima dată pot fi găsite aici.

Comentarii (8)

Se pare că în ultimii Panda versiuni mod de a merge este de a folosi df.assign:

df1 = df1.aloca(e=np.aleatoare.randn(sLength))

Nu't produc SettingWithCopyWarning.

Comentarii (1)

Face acest lucru în mod direct, prin intermediul NumPy va fi cel mai eficient:

df1['e'] = np.random.randn(sLength)

Nota mea original (foarte vechi), sugestie a fost de a utiliza "harta" (care este mult mai lent):

df1['e'] = df1['a'].map(lambda x: np.random.random())
Comentarii (2)

Super-simplu coloana misiune

Un panda dataframe este implementat ca un comandat dict de coloane.

Acest lucru înseamnă că __getitem__ [] nu poate fi utilizat doar pentru a obține o anumită coloană, dar __setitem__ [] = poate fi folosit pentru a atribui o nouă coloană.

De exemplu, acest dataframe poate avea o coloană de adăugat la simplu, cu ajutorul [] accesor

    size      name color
0    big      rose   red
1  small    violet  blue
2  small     tulip   red
3  small  harebell  blue

df['protected'] = ['no', 'no', 'no', 'yes']

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Rețineți că aceasta funcționează chiar și în cazul în care indicele de dataframe este oprit.

df.index = [3,2,1,0]
df['protected'] = ['no', 'no', 'no', 'yes']
    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

[]= este calea de a merge, dar ai grija!

Cu toate acestea, dacă aveți un pd.Seria` și să încerce să atribuiți-l la un dataframe în cazul în care indicii sunt stinse, va rula în probleme. A se vedea de exemplu:

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'])
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Acest lucru este pentru că un pd.Seria implicit are un indice enumerate la 0 la n. Și panda [] = metode de încercări pentru a fi "inteligent"

Ce de fapt se întâmplă.

Atunci când utilizați [] = metoda panda este liniște efectuează un exterior alătura sau exterior îmbinare folosind indexul de la mâna stângă dataframe și indexul de la mâna dreaptă serie. df['coloana'] = seria

Notă

Acest lucru provoacă rapid disonanță cognitivă, deoarece []= metoda este încercarea de a face o mulțime de lucruri diferite în funcție de intrare, iar rezultatul nu poate fi anticipat dacă nu știu doar cum panda funcționează. Prin urmare, aș sfaturi împotriva []= în codul de baze, dar atunci când explorarea datelor într-un notebook, este bine.

Întâmplă în jurul valorii de problema

Dacă aveți un pd.Serie și vrei atribuit de sus în jos, sau dacă sunteți de codificare productive cod și nu sunteți sigur de indicele scopul, este în valoare de ea pentru a proteja de acest tip de problema.

Ai putea să plecați la pd.Seriala unnp.ndarray` sau o "listă", acest lucru va face truc.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes']).values

sau

df['protected'] = list(pd.Series(['no', 'no', 'no', 'yes']))

Dar acest lucru nu este foarte explicit.

Un programator poate să vină și să spună "Hei, acest lucru pare redundant, am'll doar optimiza această distanță".

Mod Explicit

Stabilirea indicelui de pd.Seria a fi indicele de " df " este explicită.

df['protected'] = pd.Series(['no', 'no', 'no', 'yes'], index=df.index)

Sau mai realist, probabil ai un pd.Seria deja disponibile.

protected_series = pd.Series(['no', 'no', 'no', 'yes'])
protected_series.index = df.index

3     no
2     no
1     no
0    yes

Poate fi acum atribuite

df['protected'] = protected_series

    size      name color protected
3    big      rose   red        no
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue       yes

Cale alternativă cu df.reset_index()`

Deoarece indicele de disonanță este problema, dacă vă simțiți că indicele de dataframe ar trebui să nu dicta lucruri, puteți pur și simplu drop index, acest lucru ar trebui să fie mai rapid, dar nu este foarte curat, deoarece funcția ta acum, probabil, ** face două lucruri.

df.reset_index(drop=True)
protected_series.reset_index(drop=True)
df['protected'] = protected_series

    size      name color protected
0    big      rose   red        no
1  small    violet  blue        no
2  small     tulip   red        no
3  small  harebell  blue       yes

Notă pe df.atribui`

În timp ce df.atribuie face mai explicită ceea ce faci, de fapt, ea are toate aceleași probleme ca cele de mai sus[]=`

df.assign(protected=pd.Series(['no', 'no', 'no', 'yes']))
    size      name color protected
3    big      rose   red       yes
2  small    violet  blue        no
1  small     tulip   red        no
0  small  harebell  blue        no

Doar ai grija cu df.trimit in care coloana ta nu este numit "sine". Aceasta va provoca erori. Acest lucru facedf.atribui` pucioasa, de când există aceste tipuri de artefacte din funcție.

df.assign(self=pd.Series(['no', 'no', 'no', 'yes'])
TypeError: assign() got multiple values for keyword argument 'self'

S-ar putea spune, "ei Bine, am'll nu folosi "sine" apoi". Dar cine știe cum această funcție modificări în viitor, pentru a sprijini noi argumente. Poate că numele coloanei va fi un argument într-un nou update de panda, care cauzează probleme cu actualizarea.

Comentarii (1)

Dacă doriți să setați nouă coloană la o primă valoarea de bază (de exemplu, "Nici unul"), puteți face acest lucru: df1['e'] = None

Acest fapt s-ar atribui "obiect" tip de celula. Așa că mai târziu te're liber pentru a pune tipuri de date complexe, cum ar fi lista, în celule individuale.

Comentarii (2)

Mai simple moduri:-

data['new_col'] = list_of_values

data.loc[ : , 'new_col'] = list_of_values
Comentarii (0)

M-am temut SettingWithCopyWarning, și nu a fost't fixate cu ajutorul iloc de sintaxă. Mi DataFrame a fost creat de read_sql dintr-o sursă ODBC. Folosind o sugestie de lowtech de mai sus, următoarele au lucrat pentru mine:

df.insert(len(df.columns), 'e', pd.Series(np.random.randn(sLength),  index=df.index))

Aceasta a lucrat bine pentru a introduce coloana la sfârșitul anului. Eu nu't știu dacă este cel mai eficient, dar eu nu't ca mesajele de avertizare. Cred că există o soluție mai bună, dar nu pot't găsi, și cred că depinde de unele aspecte ale indicelui. Nota. Că acest lucru funcționează doar o singură dată și va da un mesaj de eroare dacă încercați să suprascrieți și coloană existente. Notă Ca mai sus și de la 0.16.0 atribui este cea mai bună soluție. A se vedea documentația http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Funcționează bine pentru fluxul de date de tip în cazul în care nu't suprascrie valorile intermediare.

Comentarii (0)
  1. În primul rând a crea un piton's list_of_e care are date relevante.
  2. Utilizați acest: df['e'] = list_of_e
Comentarii (1)

Dacă coloana sunteți încercarea de a adăuga o serie de variabile, atunci doar :

df["new_columns_name"]=series_variable_name #this will do it for you

Acest lucru funcționează bine, chiar dacă înlocuiți o coloană existente.trebuie doar să tastați new_columns_name același ca și coloana pe care doriți să înlocuiți.Acesta va suprascrie existente coloană de date cu noi serii de date.

Comentarii (0)

Foarte simplu de manevrat:

df.loc[:, 'NewCol'] = 'New_Val'

Exemplu:

df = pd.DataFrame(data=np.random.randn(20, 4), columns=['A', 'B', 'C', 'D'])

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
3  -0.147354  0.778707  0.479145  2.284143
4  -0.529529  0.000571  0.913779  1.395894
5   2.592400  0.637253  1.441096 -0.631468
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
8   0.606985 -2.232903 -1.358107 -2.855494
9  -0.692013  0.671866  1.179466 -1.180351
10 -1.093707 -0.530600  0.182926 -1.296494
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
18  0.693458  0.144327  0.329500 -0.655045
19  0.104425  0.037412  0.450598 -0.923387

df.drop([3, 5, 8, 10, 18], inplace=True)

df

           A         B         C         D
0  -0.761269  0.477348  1.170614  0.752714
1   1.217250 -0.930860 -0.769324 -0.408642
2  -0.619679 -1.227659 -0.259135  1.700294
4  -0.529529  0.000571  0.913779  1.395894
6   0.757178  0.240012 -0.553820  1.177202
7  -0.986128 -1.313843  0.788589 -0.707836
9  -0.692013  0.671866  1.179466 -1.180351
11 -0.143273 -0.503199 -1.328728  0.610552
12 -0.923110 -1.365890 -1.366202 -1.185999
13 -2.026832  0.273593 -0.440426 -0.627423
14 -0.054503 -0.788866 -0.228088 -0.404783
15  0.955298 -1.430019  1.434071 -0.088215
16 -0.227946  0.047462  0.373573 -0.111675
17  1.627912  0.043611  1.743403 -0.012714
19  0.104425  0.037412  0.450598 -0.923387

df.loc[:, 'NewCol'] = 0

df
           A         B         C         D  NewCol
0  -0.761269  0.477348  1.170614  0.752714       0
1   1.217250 -0.930860 -0.769324 -0.408642       0
2  -0.619679 -1.227659 -0.259135  1.700294       0
4  -0.529529  0.000571  0.913779  1.395894       0
6   0.757178  0.240012 -0.553820  1.177202       0
7  -0.986128 -1.313843  0.788589 -0.707836       0
9  -0.692013  0.671866  1.179466 -1.180351       0
11 -0.143273 -0.503199 -1.328728  0.610552       0
12 -0.923110 -1.365890 -1.366202 -1.185999       0
13 -2.026832  0.273593 -0.440426 -0.627423       0
14 -0.054503 -0.788866 -0.228088 -0.404783       0
15  0.955298 -1.430019  1.434071 -0.088215       0
16 -0.227946  0.047462  0.373573 -0.111675       0
17  1.627912  0.043611  1.743403 -0.012714       0
19  0.104425  0.037412  0.450598 -0.923387       0
Comentarii (1)

Dacă cadrului de date și Seria obiect au același index, `panda.concat, de asemenea, funcționează aici:

import pandas as pd
df
#          a            b           c           d
#0  0.671399     0.101208   -0.181532    0.241273
#1  0.446172    -0.243316    0.051767    1.577318
#2  0.614758     0.075793   -0.451460   -0.012493

e = pd.Series([-0.335485, -1.166658, -0.385571])    
e
#0   -0.335485
#1   -1.166658
#2   -0.385571
#dtype: float64

# here we need to give the series object a name which converts to the new  column name 
# in the result
df = pd.concat([df, e.rename("e")], axis=1)
df

#          a            b           c           d           e
#0  0.671399     0.101208   -0.181532    0.241273   -0.335485
#1  0.446172    -0.243316    0.051767    1.577318   -1.166658
#2  0.614758     0.075793   -0.451460   -0.012493   -0.385571

În cazul în care acestea nu't au același indice:

e.index = df.index
df = pd.concat([df, e.rename("e")], axis=1)
Comentarii (0)

Un lucru de remarcat, totuși, este că, dacă ai face

df1['e'] = Series(np.random.randn(sLength), index=df1.index)

aceasta va fi efectiv o custanga alăturați-vă pe df1.index. Deci, dacă vrei să ai o exterior** alăturați-efect, probabil, imperfect soluție este de a crea un dataframe cu valori ale indicelui de acoperire univers de date, și apoi folositi codul de mai sus. De exemplu,

data = pd.DataFrame(index=all_possible_values)
df1['e'] = Series(np.random.randn(sLength), index=df1.index)
Comentarii (0)

Înainte de a atribui o nouă coloană, dacă aveți indexate de date, aveți nevoie pentru a sorta index. Cel puțin în cazul meu am avut de a:

data.set_index(['index_column'], inplace=True)
"if index is unsorted, assignment of a new column will fail"        
data.sort_index(inplace = True)
data.loc['index_value1', 'column_y'] = np.random.randn(data.loc['index_value1', 'column_x'].shape[0])
Comentarii (0)

Permiteți-mi să adaug că, la fel ca pentru hum3, .loc n't rezolva SettingWithCopyWarning și a trebuit să recurgă ladf.insert(). În cazul meu fals pozitiv a fost generat de "fals" lanț de indexaredict['o']['e']", unde " 'e'este cea mai nouă coloană, șidict['un']` este un DataFrame vine din dicționar.

De asemenea, rețineți că, dacă știi ceea ce faci, puteți comuta de avertizare, folosind pd.opțiuni.modul.chained_assignment = None` și decât să-l utilizați una dintre celelalte soluții oferite aici.

Comentarii (0)

Am fost în căutarea pentru un mod general de a adăuga o coloană de numpy.nan pentru o dataframe, fără a se mutSettingWithCopyWarning`.

Din cele următoarele:

  • răspunsurile aici
  • această întrebare cu privire la trecerea unei variabile ca un cuvânt cheie argument
  • această metodă pentru a genera un numpy matrice de NaNs în linie

Am venit cu asta:

col = 'column_name'
df = df.assign(**{col:numpy.full(len(df), numpy.nan)})
Comentarii (0)

pentru a insera o nouă coloană la o anumită locație (0 <= loc <= cantitatea de coloane), într-un cadru de date, trebuie doar să utilizați Dataframe.insert:

DataFrame.insert(loc, column, value)

Prin urmare, dacă doriți să adăugați coloana e la sfârșitul unui cadru de date numit df, puteți folosi:

e = [-0.335485, -1.166658, -0.385571]    
DataFrame.insert(loc=len(df.columns), column='e', value=e)

valoare poate fi o Serie, un număr întreg (în cazul în care toate celulele se umplu cu aceasta valoare), sau o mulțime-ca structura

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.insert.html

Comentarii (0)

Pentru a adăuga o nouă coloană, 'e', a datelor existente cadru

 df1.loc[:,'e'] = Series(np.random.randn(sLength))
Comentarii (1)

Pentru motive de exhaustivitate - încă o soluție folosind DataFrame.eval() metoda:

Date:

In [44]: e
Out[44]:
0    1.225506
1   -1.033944
2   -0.498953
3   -0.373332
4    0.615030
5   -0.622436
dtype: float64

In [45]: df1
Out[45]:
          a         b         c         d
0 -0.634222 -0.103264  0.745069  0.801288
4  0.782387 -0.090279  0.757662 -0.602408
5 -0.117456  2.124496  1.057301  0.765466
7  0.767532  0.104304 -0.586850  1.051297
8 -0.103272  0.958334  1.163092  1.182315
9 -0.616254  0.296678 -0.112027  0.679112

Soluție:

In [46]: df1.eval("e = @e.values", inplace=True)

In [47]: df1
Out[47]:
          a         b         c         d         e
0 -0.634222 -0.103264  0.745069  0.801288  1.225506
4  0.782387 -0.090279  0.757662 -0.602408 -1.033944
5 -0.117456  2.124496  1.057301  0.765466 -0.498953
7  0.767532  0.104304 -0.586850  1.051297 -0.373332
8 -0.103272  0.958334  1.163092  1.182315  0.615030
9 -0.616254  0.296678 -0.112027  0.679112 -0.622436
Comentarii (0)