Tratando de enseñarme pandas ... y jugando con diferentes tipos

Tengo un df de la siguiente manera

df = pd.DataFrame({'ID':[0,2,"bike","cake"], 'Course':['Test','Math','Store','History'] })
print(df)
    ID  Course
0   0   Test
1   2   Math
2   bike    Store
3   cake    History

El tipo de ID es, por supuesto, un objeto. Lo que quiero hacer es eliminar cualquier fila en el DF si la ID tiene una cadena.

Pensé que esto sería tan simple como ...

df.ID.filter(regex='[\w]*')

Pero esto devuelve todo, ¿hay un método seguro para lidiar con tales cosas?

5
Datanovice 8 sep. 2018 a las 00:48

3 respuestas

La mejor respuesta

Puedes usar to_numeric

df[pd.to_numeric(df.ID,errors='coerce').notnull()]
Out[450]: 
  Course ID
0   Test  0
1   Math  2
5
YOBEN_S 7 sep. 2018 a las 21:51

La respuesta de Wen es la forma correcta (y más rápida) de resolver esto, pero para explicar por qué su expresión regular no funciona, tienes que entender lo que significa \w.

\w coincide con cualquier carácter de palabra, que incluye [a-zA-Z0-9_]. Entonces, lo que está haciendo coincidir actualmente con incluye dígitos, por lo que todo coincide. Un enfoque válido de expresión regular sería:

df.loc[df.ID.astype(str).str.match(r'\d+')]
  ID Course
0  0   Test
1  2   Math

El segundo problema es su uso de filter. No está filtrando su fila ID, está filtrando su índice. Una solución válida con filter sería la siguiente:

df.set_index('ID').filter(regex=r'^\d+$', axis=0)
   Course
ID
0    Test
2    Math
4
user3483203 7 sep. 2018 a las 22:06

Otra opción es convertir la columna a cadena y usar str.match:

print(df[df['ID'].astype(str).str.match("\d+")])
#  Course ID
#0   Test  0
#1   Math  2

Su código no funciona, porque como se indica en los documentos para pandas.DataFrame.filter:

Tenga en cuenta que esta rutina no filtra un marco de datos en su contenido. El filtro se aplica a las etiquetas del índice.

4
pault 7 sep. 2018 a las 21:59