2017-05-06 11 views
3

J'ai un ensemble de données comme celui-ci où il manque des données pour certaines années.Pandas-Ajouter des années manquantes dans les données de séries temporelles avec des années dupliquées

County Year Pop 
12  1999 1.1 
12  2001 1.2 
13  1999 1.0 
13  2000 1.1 

Je veux quelque chose comme

County Year Pop 
12  1999 1.1 
12  2000 NaN 
12  2001 1.2 
13  1999 1.0 
13  2000 1.1 
13  2001 nan 

Je index essayé de placer à l'autre et puis en utilisant réindexation avec un autre dataframe de la méthode juste ans (mentionné ici Pandas: Add data for missing months) mais il me donne une erreur cant réindexer avec double valeurs. J'ai aussi essayé df.loc mais il a le même problème. J'ai même essayé une jointure externe complète avec df vierge des années justes mais cela n'a pas fonctionné.

Comment puis-je résoudre ce problème?

Répondre

5

Faire un multiindice si vous ne disposez pas de doublons:

df.set_index(['County', 'Year'], inplace=True) 

Ensuite, la construction d'une multiindice complète avec toutes les combinaisons:

index = pd.MultiIndex.from_product(df.index.levels) 

Puis réindexation:

df.reindex(index) 

Le la construction du MultiIndex n'est pas testée et peut nécessiter un petit ajustement (par exemple, si une année est entièrement absente de tous les comtés), mais je pense que vous avez l'idée.

+0

Je suis tellement en utilisant cela! – piRSquared

2

Vous pouvez utiliser pivot_table:

In [11]: df.pivot_table(values="Pop", index="County", columns="Year") 
Out[11]: 
Year 1999 2000 2001 
County 
12  1.1 NaN 1.2 
13  1.0 1.1 NaN 

et stack le résultat (une série est nécessaire):

In [12]: df.pivot_table(values="Pop", index="County", columns="Year").stack(dropna=False) 
Out[12]: 
County Year 
12  1999 1.1 
     2000 NaN 
     2001 1.2 
13  1999 1.0 
     2000 1.1 
     2001 NaN 
dtype: float64 
+0

Bonjour Andy! Je ne pense pas avoir déjà répondu à une question :-) – piRSquared

+0

@piRSquared c'est sûrement impossible! –

1

Ou vous pouvez essayer un peu de magie noire: P

min_year, max_year = df.Year.min(), df.Year.max() 

df.groupby('County').apply(lambda g: g.set_index("Year").reindex(range(min_year, max_year+1))).drop("County", axis=1).reset_index() 
2

Je pars du principe que vous voudrez peut-être ajouter toutes les années entre le minimum et le maximum. Il se peut que vous manquiez 2000 pour les deux comtés 12 et 13.

Je vais construire un pd.MultiIndexfrom_product utilisant unique valeurs de la colonne 'County' et toutes les années entières entre et y compris les min et max années dans la colonne 'Year'.

Note: cette solution remplit même si elles ne sont pas actuellement présents dans toutes les années manquantes.

mux = pd.MultiIndex.from_product([ 
     df.County.unique(), 
     range(df.Year.min(), df.Year.max() + 1) 
    ], names=['County', 'Year']) 

df.set_index(['County', 'Year']).reindex(mux).reset_index() 

    County Year Pop 
0  12 1999 1.1 
1  12 2000 NaN 
2  12 2001 1.2 
3  13 1999 1.0 
4  13 2000 1.1 
5  13 2001 NaN 
1

Vous avez mentionné que vous avez essayé de joindre une df vierge et que cette approche peut fonctionner.

Configuration:

df = pd.DataFrame({'County': {0: 12, 1: 12, 2: 13, 3: 13}, 
'Pop': {0: 1.1, 1: 1.2, 2: 1.0, 3: 1.1}, 
'Year': {0: 1999, 1: 2001, 2: 1999, 3: 2000}}) 

Solution

#create a new blank df with all the required Years for each County 
df_2 = pd.DataFrame(np.r_[pd.tools.util.cartesian_product([df.County.unique(),np.arange(1999,2002)])].T, columns=['County','Year']) 

#Left join the new dataframe to the existing dataframe to populate the Pop values. 
pd.merge(df_2,df,on=['Year','County'],how='left') 
Out[73]: 
    County Year Pop 
0  12 1999 1.1 
1  12 2000 NaN 
2  12 2001 1.2 
3  13 1999 1.0 
4  13 2000 1.1 
5  13 2001 NaN 
+0

Merci beaucoup, je n'ai pas inclus le comté dans mon DF vierge. je me vois mon erreur maintenant ... Merci! – ks2882

+0

Vous êtes les bienvenus. – Allen