2017-08-10 3 views
1

J'ai un cadre de données pandas avec une colonne sur les dates dans ce format "2016-05-03" Ce sont des chaînes btw. J'ai besoin de les convertir en un entier à partir d'une chaîne et de les séparer au trait d'union ('-') et de ne les extraire que pour l'année donc [0].Comment transformer une série de chaînes d'une colonne pandas en entiers

C'est ce que j'ai essayé de transformer la chaîne en un entier:

tyc.startDate = tyc.startDate.astype(np.int64) 

Mais il est de retour et d'erreur:

ValueError: invalide littérale int() avec la base 10: « 2015 -06 à 01'

et ce que je l'ai fait pour séparer:

tyc.startDate.str.split('-')[0] 

et

tyc.startDate.str.split('-', [0]) 

mais cela ne fonctionne pas non plus, il est le fractionnement et le retour d'une liste de toutes les lignes dans la colonne sous cette forme: [ « 2015 », « 06 », « 01 »] et je veux juste divisé pour l'année!

Je suis sûr qu'il existe un moyen simple de simplement convertir en int et scinder pour ('-') à la position 0 et ensuite mettre cela dans la df comme une nouvelle colonne, s'il vous plaît aider!

Répondre

0

Je crois vos données contiennent des NaN s ou des valeurs non datetime:

tyc = pd.DataFrame({'startDate':['2016-05-03','2017-05-03', np.nan], 
        'col':[1,2,3]}) 
print (tyc) 
    col startDate 
0 1 2016-05-03 
1 2 2017-05-03 
2 3   NaN 

Utilisez str[0] pour le retour premier li la première valeur de chaque rangée. Mais il y a un problème - certains NaNs, qui ne peut être converti en int (soit la conception) - si la sortie est flotteurs:

print (tyc.startDate.str.split('-').str[0].astype(float)) 
0 2016.0 
1 2017.0 
2  NaN 
Name: startDate, dtype: float64 

Une autre solution est de convertir en datetime par to_datetime et parse année par year:

print (pd.to_datetime(tyc.startDate, errors='coerce')) 
0 2016-05-03 
1 2017-05-03 
2   NaT 
Name: startDate, dtype: datetime64[ns] 

print (pd.to_datetime(tyc.startDate, errors='coerce').dt.year) 
0 2016.0 
1 2017.0 
2  NaN 
Name: startDate, dtype: float64 

Solutions pour supprimer NaN s:

tyc['year'] = pd.to_datetime(tyc.startDate, errors='coerce').dt.year 
print (tyc) 
    col startDate year 
0 1 2016-05-03 2016.0 
1 2 2017-05-03 2017.0 
2 3   NaN  NaN 

1.

Retirez toutes les lignes avec NaN s par dropna puis jeté int:

tyc = tyc.dropna(subset=['year']) 
tyc['year'] = tyc['year'].astype(int) 
print (tyc) 
    col startDate year 
0 1 2016-05-03 2016 
1 2 2017-05-03 2017 

2.

Remplacer NaN s par une valeur int comme 1 par fillna puis jeté à int:

tyc['year'] = tyc['year'].fillna(1).astype(int) 
print (tyc) 
    col startDate year 
0 1 2016-05-03 2016 
1 2 2017-05-03 2017 
2 3   NaN  1 
+0

Merci beaucoup qui fonctionne très bien aussi! –

+0

Hmm, vous écrivez dans les commentaires un problème avec une autre solution, donc une autre solution fonctionne bien, donc accepté ou pas? – jezrael

+0

accepté –

0

Vous pouvez utiliser apply:

def mod_strings(date_str): 
    try: 
     return int(date_str.split('-')[0]) 
    except (AttributeError, IndexError): # in case value is not as 
              # expected returning original value 
     return date_str 

tyc.startDate = tyc.startDate.apply(mod_strings) 

mais il pourrait être plus facile de convertir simplement toute la colonne de chaînes à des objets de date et puis utilisez tyc.startDate = tyc.startDate.dt.year (en supposant version Pandas> = 0.16)

+0

Hey @DeepSpace! Merci pour cela. Je l'ai essayé mais j'obtiens cette erreur: AttributeError: l'objet 'float' n'a aucun attribut 'split' –

+0

@ s.23 Il est évident que certaines des lignes contiennent un objet flottant et non une chaîne dans la colonne 'startDate'. Vous devez être sûr des types de données avec lesquels vous travaillez. – DeepSpace

+0

Alors, est-ce que je devrais utiliser une exception? –