web-dev-qa-db-fra.com

Convertissez des données entières de minuscules en majuscules avec les pandas

J'ai une base de données comme celle affichée ci-dessous: 

# Create an example dataframe about a fictional army
raw_data = {'regiment': ['Nighthawks', 'Nighthawks', 'Nighthawks', 'Nighthawks'],
            'company': ['1st', '1st', '2nd', '2nd'],
            'deaths': ['kkk', 52, '25', 616],
            'battles': [5, '42', 2, 2],
            'size': ['l', 'll', 'l', 'm']}
df = pd.DataFrame(raw_data, columns = ['regiment', 'company', 'deaths', 'battles', 'size'])

 enter image description here

Mon objectif est de transformer chaque chaîne à l'intérieur de la structure de données en majuscule afin qu'elle ressemble à ceci:

 enter image description here

Remarque: tous les types de données sont des objets et ne doivent pas être modifiés. la sortie doit contenir tous les objets. Je veux éviter de convertir chaque colonne une par une ... Je voudrais le faire en général sur tout le cadre de données éventuellement.

Ce que j’ai essayé jusqu’à présent, c’est de le faire mais sans succès

df.str.upper()
7
Federico Gentile

astype () convertira chaque série en l'objet dtype (chaîne), puis appellera la méthode str () sur la série convertie pour obtenir la chaîne littéralement et appeler la fonction upper () dessus. Notez qu'après cela, le type de toutes les colonnes devient object.

In [17]: df
Out[17]: 
     regiment company deaths battles size
0  Nighthawks     1st    kkk       5    l
1  Nighthawks     1st     52      42   ll
2  Nighthawks     2nd     25       2    l
3  Nighthawks     2nd    616       2    m

In [18]: df.apply(lambda x: x.astype(str).str.upper())
Out[18]: 
     regiment company deaths battles size
0  NIGHTHAWKS     1ST    KKK       5    L
1  NIGHTHAWKS     1ST     52      42   LL
2  NIGHTHAWKS     2ND     25       2    L
3  NIGHTHAWKS     2ND    616       2    M

Vous pouvez ultérieurement convertir la colonne 'batailles' en numérique, en utilisant to_numeric () :

In [42]: df2 = df.apply(lambda x: x.astype(str).str.upper())

In [43]: df2['battles'] = pd.to_numeric(df2['battles'])

In [44]: df2
Out[44]: 
     regiment company deaths  battles size
0  NIGHTHAWKS     1ST    KKK        5    L
1  NIGHTHAWKS     1ST     52       42   LL
2  NIGHTHAWKS     2ND     25        2    L
3  NIGHTHAWKS     2ND    616        2    M

In [45]: df2.dtypes
Out[45]: 
regiment    object
company     object
deaths      object
battles      int64
size        object
dtype: object
17
Nehal J Wani

cela peut être résolu par l'opération applymap suivante:

df = df.applymap(lambda s:s.lower() if type(s) == str else s)
9
VincentQT

Puisque str ne fonctionne que pour les séries, vous pouvez l'appliquer à chaque colonne individuellement, puis concaténer

In [6]: pd.concat([df[col].astype(str).str.upper() for col in df.columns], axis=1)
Out[6]: 
     regiment company deaths battles size
0  NIGHTHAWKS     1ST    KKK       5    L
1  NIGHTHAWKS     1ST     52      42   LL
2  NIGHTHAWKS     2ND     25       2    L
3  NIGHTHAWKS     2ND    616       2    M

Edit: performance performance

In [10]: %timeit df.apply(lambda x: x.astype(str).str.upper())
100 loops, best of 3: 3.32 ms per loop

In [11]: %timeit pd.concat([df[col].astype(str).str.upper() for col in df.columns], axis=1)
100 loops, best of 3: 3.32 ms per loop

Les deux réponses fonctionnent également sur une petite trame de données. 

In [15]: df = pd.concat(10000 * [df])

In [16]: %timeit pd.concat([df[col].astype(str).str.upper() for col in df.columns], axis=1)
10 loops, best of 3: 104 ms per loop

In [17]: %timeit df.apply(lambda x: x.astype(str).str.upper())
10 loops, best of 3: 130 ms per loop

Sur une grande base de données, ma réponse est légèrement plus rapide.

3
IanS

si vous souhaitez conserver l’utilisation de type est isinstance(obj,type)

df.apply(lambda x: x.str.upper().str.strip() if isinstance(x, object) else x)
1
Alex Montoya

essaye ça 

df2 = df2.apply(lambda x: x.str.upper() if x.dtype == "object" else x)  
0
Ganesh Bhat