4 votes

Convertir les valeurs des colonnes en minuscules uniquement si elles sont des chaînes de caractères.

J'ai de gros problèmes pour convertir une colonne en minuscules. Ce n'est pas aussi simple que d'utiliser :

df['my_col'] = df['my_col'].str.lower()

parce que j'itère sur un grand nombre d'images de données et que certaines d'entre elles (mais pas toutes) contiennent à la fois des chaînes et des entiers dans la colonne concernée. La fonction inférieure, si elle est appliquée comme ci-dessus, déclenche alors une exception :

AttributeError: Can only use .str accessor with string values, which use np.object_ dtype in pandas

Plutôt que de forcer le type à être une chaîne de caractères, j'aimerais évaluer si les valeurs sont des chaînes de caractères et ensuite - si c'est le cas - les convertir en minuscules, et - si ce ne sont pas des chaînes de caractères - les laisser telles quelles. Je pensais que cela fonctionnerait :

df = df.apply(lambda x: x.lower() if(isinstance(x, str)) else x)

Mais ça ne marche pas... probablement parce que je néglige quelque chose d'évident, mais je ne vois pas ce que c'est !

Mes données ressemblent à ceci :

                          OS    Count
0          Microsoft Windows     3
1                   Mac OS X     4
2                      Linux     234
3    Don't have a preference     0
4  I prefer Windows and Unix     3
5                       Unix     2
6                        VMS     1
7         DOS or ZX Spectrum     2

7voto

ysearka Points 2280

Le test dans votre fonction lambda n'est pas tout à fait correct, mais vous n'étiez pas loin de la vérité :

df.apply(lambda x: x.str.lower() if(x.dtype == 'object') else x)

Avec le cadre de données et la sortie :

df = pd.DataFrame(columns = ['OS','Count'])
df.OS = ["Microsoft Windows","Mac OS X","Linux","Don't have a preference",\
      "I prefer Windows and Unix","Unix","VMS","DOS or ZX Spectrum"]
df.Count = [3,4,234,0,3,2,1,2]
df = df.apply(lambda x: x.str.lower() if(x.dtype == 'object') else x)
df

    OS                          Count
0   microsoft windows           3
1   mac os x                    4
2   linux                       234
3   don't have a preference     0
4   i prefer windows and unix   3
5   unix                        2
6   vms                         1
7   dos or zx spectrum          2

5voto

coldspeed Points 111053

Quel est le type de ces colonnes pour commencer ? object ? Si oui, vous devriez les convertir :

df['my_col'] = df.my_col.astype(str).str.lower()

MVCE :

In [1120]: df
Out[1120]: 
   Col1
0   VIM
1   Foo
2  test
3     1
4     2
5     3
6   4.5
7   OSX

In [1121]: df.astype(str).Col1.str.lower()
Out[1121]: 
0     vim
1     foo
2    test
3       1
4       2
5       3
6     4.5
7     osx
Name: Col1, dtype: object

In [1118]: df.astype(str).Col1.str.lower().dtype
Out[1118]: dtype('O')

Si vous voulez faire de l'arithmétique sur ces lignes, vous ne devriez probablement pas mélanger str et les types numériques.

Cependant, si c'est effectivement votre cas, vous pouvez effectuer un tapering en numérique en utilisant pd.to_numeric(..., errors='coerce') :

In [1123]: pd.to_numeric(df.Col1, errors='coerce')
Out[1123]: 
0    NaN
1    NaN
2    NaN
3    1.0
4    2.0
5    3.0
6    4.5
7    NaN
Name: Col1, dtype: float64

Vous pouvez travailler avec les NaNs, mais remarquez les dtype maintenant.

1voto

Narahari B M Points 43

D'après les deux réponses ci-dessus, je pense que cette façon de faire est un peu plus sûre :

Notez le astype(str)

df_lower=df.apply(lambda x: x.astype(str).str.lower() if(x.dtype == 'object') else x)

Parce que si votre colonne de chaînes de caractères ne contient par hasard que des chiffres dans certaines lignes, ne pas faire astype(str) les convertit en nan. Cette méthode est peut-être un peu plus lente, mais elle ne convertit pas les lignes contenant uniquement des chiffres en nan.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X