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'])
Mon objectif est de transformer chaque chaîne à l'intérieur de la structure de données en majuscule afin qu'elle ressemble à ceci:
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()
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
cela peut être résolu par l'opération applymap suivante:
df = df.applymap(lambda s:s.lower() if type(s) == str else s)
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.
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)
essaye ça
df2 = df2.apply(lambda x: x.str.upper() if x.dtype == "object" else x)