2017-10-15 2 views
2

J'essaie de filtrer une trame de données python basée sur une sous-chaîne dans l'une des colonnes.Python, Pandas: Filtrer les lignes d'une trame de données en fonction de la fonction

Si le numéro à la position 13 & 14 du champ ID est < = 9, je veux garder la ligne, si c'est> 9, je veux laisser tomber la ligne.

Exemple:

ABCD-3Z-A93Z-01A-11R-A37O-07 -> garder

ABCD-3Z-A93Z-11A-11R-A37O-07 -> Chute

J'ai réussi à obtenir la solution ci-dessous, mais je pense qu'il doit y avoir un moyen plus rapide et plus efficace.

import pandas as pd 

# Enter some data. We want to filter out all rows where the number at pos 13,14 > 9 
df = {'ID': ['ABCD-3Z-A93Z-01A-11R-A37O-07', 'ABCD-6D-AA2E-11A-11R-A37O-07', 'ABCD-6D-AA2E-01A-11R-A37O-07', 
      'ABCD-A3-3307-01A-01R-0864-07', 'ABCD-6D-AA2E-01A-11R-A37O-07', 'ABCD-6D-AA2E-10A-11R-A37O-07', 
      'ABCD-6D-AA2E-09A-11R-A37O-07'], 
     'year': [2012, 2012, 2013, 2014, 2014, 2017, 2015] 
} 
# convert to df 
df = pd.DataFrame(df) 

# define a function that checks if position 13&15 are > 9. 
def filter(x): 
    # that, if x is a string, 
    if type(x) is str: 
     if int(float(x[13:15])) <= 9: 
      return True 
     else: 
      return False 
    else: 
     return False 

# apply function 
df['KeepRow'] = df['ID'].apply(filter) 
print(df) 

# Now filter out rows where "KeepRow" = False 
df = df.loc[df['KeepRow'] == True] 
print(df) 
# drop the column "KeepRow" as we don't need it anymore 
df = df.drop('KeepRow', axis=1) 
print(df) 

Répondre

2

Utilisez indexing with str pour les valeurs par positions, puis convertir en float et filtrer par boolean indexing:

df = df[df['ID'].str[13:15].astype(float) <=9] 
print(df) 
          ID year 
0 ABCD-3Z-A93Z-01A-11R-A37O-07 2012 
2 ABCD-6D-AA2E-01A-11R-A37O-07 2013 
3 ABCD-A3-3307-01A-01R-0864-07 2014 
4 ABCD-6D-AA2E-01A-11R-A37O-07 2014 
6 ABCD-6D-AA2E-09A-11R-A37O-07 2015 

Détail:

print(df['ID'].str[13:15]) 
0 01 
1 11 
2 01 
3 01 
4 01 
5 10 
6 09 
Name: ID, dtype: object 
+1

Brillant, merci! Tellement plus facile! Stackoverflow me dit que je ne peux accepter la réponse que dans 5 minutes. Je le ferai alors. – Laura

2

Je pense que vous pouvez simplement filtrer à partir de 13 symbole de votre chaîne:

das comme pd

# Enter some data. We want to filter out all rows where the number at pos 13,14 > 9 
df = pd.DataFrame({ 
    'ID': ['ABCD-3Z-A93Z-01A-11R-A37O-07', 
      'ABCD-6D-AA2E-11A-11R-A37O-07', 
      'ABCD-6D-AA2E-01A-11R-A37O-07', 
      'ABCD-A3-3307-01A-01R-0864-07', 
      'ABCD-6D-AA2E-01A-11R-A37O-07', 
      'ABCD-6D-AA2E-10A-11R-A37O-07', 
      'ABCD-6D-AA2E-09A-11R-A37O-07'], 
    'year': [2012, 2012, 2013, 2014, 2014, 2017, 2015] 
}) 
# convert to df 

df['KeepRow'] = df['ID'].apply(lambda x: x[13] == '0') 

ou simplement:

df[df['ID'].apply(lambda x: x[13] == '0')] 
+0

Merci! Cela fonctionne très bien aussi! – Laura