2017-10-20 16 views
1

J'ai trois fichiers csv que nous pouvons appeler a, b et c. Fichier a des informations géographiques, y compris les codes postaux. Le fichier b contient des données statistiques. Le fichier c a seulement des codes postaux.Les erreurs clés pour l'objet après la conversion en une chaîne dans les pandas?

J'ai utilisé pour convertir pandas géants a et b à dataframes (a_df et b_df) que je l'habitude de se joindre à l'information qui était une colonne partagée entre ces deux dataframes (intermediate_df). Le fichier c a été lu et converti en une image dont le code postal était un type entier. J'ai dû convertir cela en chaîne afin que les codes postaux ne soient pas traités comme des entiers. Cependant, c_df traite cette colonne comme des objets après que je l'ai convertie en chaîne ce qui signifie que je ne peux pas faire une jointure entre c_df et intermediate_df pour rendre final_df.

Pour illustrer ce que je veux dire:

a_data = pd.read_csv("a.csv") 
b_data = pd.read_csv("b.csv", dtype={'zipcode': 'str'}) 
a_df = pd.DataFrame(a_data) 
b_df = pd.DataFrame(b_data) 

# file c conversion 
c_data = pd.read_csv("slcsp.csv", dtype={'zipcode': 'str'}) 
print ("This is c data types: ", c_data.dtypes) 
c_conversion = c_data['zipcode'].apply(str) 
print ("This is c_conversion data types: ", c_conversion.dtypes) 
c_df = pd.DataFrame(c_conversion) 
print ("This is c_df data types: ", c_df.dtypes) 

# Joining on the two common columns to avoid duplicates 
joined_ab_df = pd.merge(a_df, a_df, on =['state', 'area']) 

# Dropping columns that are not needed anymore 
ab_for_analysis_df = joined_ab.drop(['county_code','name', 'area'], axis=1) 

# Time to analyze this dataframe. Let's pick out only the silver values for 
a specific attribute 
silver_only_df = (ab_for_analysis_df[filtered_df.metal_name == 'Silver']) 

# Getting second lowest value of silver only 
sorted_silver = silver_only_df.groupby('zipcode')['rate'].nsmallest(2) 
sorted_silver_df = sorted_silver.to_frame() 

print ("We cleaned up our data. Let's join the dataframes.") 
print ("Final result...") 
print (c_df.dtypes) 
final_df = pd.merge(sorted_silver_df,c_df, on ='zipcode') 

C'est ce que nous obtenons après avoir fait rouler:

This is c_data types: zipcode  object 
rate  float64 
dtype: object 
This is c_conversion_data types: object 
This is c_df data types: zipcode object 
dtype: object 
zipcode object 
dtype: object 

We cleaned up our data. Let's join the dataframes. 
This is the final result... 
KeyError: 'zipcode' 

Toute idée pourquoi il a changé les types de données et comment puis-je puis fixer donc tout se joint à la fin?

+1

Pouvez-vous ajouter 'impression (c_df.columns)' et 'impression (') sorted_silver_df.columns – Dark

+0

Ainsi, le deuxième à la dernière ligne: 'imprimer (c_df.dtypes) 'ne s'imprime pas non plus? C'est bizarre. Je recommande d'utiliser ipython/jupyter et la fonction magique '% debug', de cette façon vous pouvez passer à travers ce genre d'erreurs. –

+0

C'est un problème étrange. @AndyHayden. L'impression c_df.dtypes fonctionne bien que cela donne des résultats bizarres –

Répondre

2

Si converti en str toujours la sortie dtype est l'objet.

Pour vérifier strings besoin de vérifier type:

print (c_data['zipcode'].apply(type)) 

Pour votre dernière erreur:

besoin reset_index, parce que d'autre zipcode est index, pas la colonne:

sorted_silver_df = silver_only_df.groupby('zipcode')['rate'].nsmallest(2).reset_index() 
final_df = pd.merge(sorted_silver_df,c_df, on ='zipcode') 

Merci, Andy pour alternative (non testé):

sorted_silver_df = silver_only_df.groupby('zipcode', as_index=False)['rate'].nsmallest(2) 
final_df = pd.merge(sorted_silver_df,c_df, on ='zipcode') 

Ou utilisez left_index=True et riht_on dans merge:

sorted_silver = silver_only_df.groupby('zipcode')['rate'].nsmallest(2) 
sorted_silver_df = sorted_silver.to_frame() 
final_df = pd.merge(sorted_silver_df,c_df, right_on ='zipcode', left_index=True) 
+0

peut également utiliser 'as_index = False' dans le groupby (au lieu de' reset_index') –

+0

Merci, je l'ajoute pour répondre. Mais parfois cela ne fonctionne pas, donc plutôt j'ajoute avis non testé;) – jezrael

+0

Merci. Je ne peux pas sembler obtenir que pour travailler soit: '' 50 'Nom: code postal, DTYPE: object' ' Voici les types c_data: object' 'Voici les types de données c_df: code postal object' ' dtype: object' 'objet code postal' ' dtype: objet' 'Nous avons nettoyé nos données. Rejoignons les dataframes. » ' Résultat final ...raise ValueError ('len (right_on) doit être égal au nombre' ' ' ValueError: len (right_on) doit être égal au nombre de niveaux dans l'index'' 'of" left "' –