2013-02-20 29 views
7

Sto lavorando attraverso un'assegnazione con Panda e sto usando np.where() per creare aggiungere una colonna a una Panda dataframe con tre possibili valori:Pandas Colonna di costruzione con np.where()

fips_df['geog_type'] = np.where(fips_df.fips.str[-3:] != '000', 'county', np.where(fips_df.fips.str[:] == '00000', 'country', 'state')) 

lo stato della dataframe dopo aver aggiunto la colonna è così:

costruzione
print fips_df[:5] 

    fips   geog_entity fips_prefix geog_type 
0 00000  UNITED STATES   00 country 
1 01000    ALABAMA   01  state 
2 01001 Autauga County, AL   01 county 
3 01003 Baldwin County, AL   01 county 
4 01005 Barbour County, AL   01 county 

questa colonna è testato da due asserisce. Il primo passa e il secondo fallisce.

## check the numbers of geog_type 

assert set(fips_df['geog_type'].value_counts().iteritems()) == set([('state', 51), ('country', 1), ('county', 3143)]) 

assert set(fips_df.geog_type.value_counts().iteritems()) == set([('state', 51), ('country', 1), ('county', 3143)]) 

Qual è la differenza tra chiamare colonne come fips_df.geog_type e fips_df [ 'geog_type'] che causa la mia seconda assert a fallire?

risposta

2

E dovrebbe essere lo stesso (e sarà il più delle volte) ...

Una situazione non è è quando si dispone già di un attributo o un metodo impostato con quel valore (in questo caso ha vinto 't essere sovrascritti e quindi la colonna non sarà accessibile con la notazione):

In [1]: df = pd.DataFrame([[1, 2] ,[3 ,4]]) 

In [2]: df.A = 7 

In [3]: df.B = lambda: 42 

In [4]: df.columns = list('AB') 

In [5]: df.A 
Out[5]: 7 

In [6]: df.B() 
Out[6]: 42 

In [7]: df['A'] 
Out[7]: 
0 1 
1 3 
Name: A 

interessante, dot notation for accessing columns non è menzionato nella selection syntax.

+1

http://pandas.pydata.org/pandas-docs/dev/dsintro.html#dataframe-column-attribute-access-and-ipython-completion –

+0

Grazie! @andyhayden. Ho pensato che entrambi i metodi di accesso alle colonne fossero validi, sebbene non avessi visto quella parte della documentazione di Pandas. Forse il problema sta venendo dall'asserzione affermazione – ajrenold

+0

@ajrenold me too tbh, questo è l'unico modo che posso pensare, potrebbe valere la pena provare ad affermare df.A == df ['A']? –

3

Nel caso, è possibile creare una nuova colonna con molto meno sforzo. Es .:

In [1]: import pandas as pd 

In [2]: import numpy as np 

In [3]: df = pd.DataFrame(np.random.uniform(size=10)) 

In [4]: df 
Out[4]: 
      0 
0 0.366489 
1 0.697744 
2 0.570066 
3 0.756647 
4 0.036149 
5 0.817588 
6 0.884244 
7 0.741609 
8 0.628303 
9 0.642807 

In [5]: categorize = lambda value: "ABC"[int(value > 0.3) + int(value > 0.6)] 

In [6]: df["new_col"] = df[0].apply(categorize) 

In [7]: df 
Out[7]: 
      0 new_col 
0 0.366489  B 
1 0.697744  C 
2 0.570066  B 
3 0.756647  C 
4 0.036149  A 
5 0.817588  C 
6 0.884244  C 
7 0.741609  C 
8 0.628303  C 
9 0.642807  C 
+0

Questo è sicuramente un modo più bello per eseguire il calcolo vero e proprio, int non è necessario :) –

+0

@AndyHayden true, 'int' è entrato di nascosto durante il debug. –

+0

Grazie per aver suggerito un'alternativa @MaximYegorushkin! La mia nuova colonna fips ['geog_type'] è creata in base a una stringa di numeri in cui il modello dei numeri consente la categorizzazione, ma non il valore numerico, quindi non sono sicuro che il tuo metodo funzioni con le stringhe. Ho modificato la mia domanda e inserito un output da DataFrame dopo la creazione della nuova colonna. – ajrenold

Problemi correlati