J'ai donc ce dataframe:
RangeIndex: 57172 entries, 0 to 57171 Data columns (total 8 columns): filename 57172 non-null object width 57172 non-null int64 height 57172 non-null int64 class 57172 non-null object xmin 57172 non-null int64 ymin 57172 non-null int64 xmax 57172 non-null int64 ymax 57172 non-null int64 dtypes: int64(6), object(2) memory usage: 3.5+ MB
Qui contient dans la colonne appelée "class" ont les valeurs uniques "Panel", "P + SD" et "HS + P + SD" . Je veux compter le nombre de lignes avec ces valeurs, alors j'ai essayé ceci:
56988 0 0
Cela m'a donné cette sortie:
print(len(split_df[split_df["class"].str.contains('Panel')]))
print(len(split_df[split_df["class"].str.contains('HS+P+SD')]))
print(len(split_df[split_df["class"].str.contains('P+SD')]))
Ceci est incorrect comme vous pouvez le voir clairement sur la base de l'extrait de DataFrame fourni ci-dessus, pourquoi tout est-il compté correctement pour Panel mais rien n'est compté pour les deux autres noms de "classe"?
Voici la sortie de split_df.info :
filename width height class xmin ymin xmax ymax 0 128782.JPG 640 512 Panel 36 385 119 510 1 128782.JPG 640 512 Panel 124 388 207 510 2 128782.JPG 640 512 Panel 210 390 294 511 3 128782.JPG 640 512 Panel 294 395 380 510 4 128782.JPG 640 512 Panel 379 398 466 511 5 128782.JPG 640 512 Panel 465 402 553 510 6 128782.JPG 640 512 P+SD 552 402 638 510 7 128782.JPG 640 512 P+SD 558 264 638 404 ... ... 57170 128782.JPG 640 512 P+SD 36 242 121 383 57171 128782.JPG 640 512 HS+P+SD 36 97 122 242 57172 128782.JPG 640 512 P+SD 214 106 304 250
Je ne peux pas pour la vie de moi comprendre ce qui ne va pas. Toute aide est appréciée.
3 Réponses :
pd.Series. str.contains a regex = True par défaut. Puisque + est un caractère spécial dans l'expression régulière, utilisez regex = False , re.escape ou \ en échappant:
L = ['Panel', 'HS+P+SD', 'P+SD'] counts = df.loc[df['class'].isin(L), 'class'].value_counts()
Je veux compter le nombre de lignes avec ces valeurs
S'il s'agit de votre problème principal et que vous ne voulez pas qu'un compte 'P + SD' inclue 'HS + P + SD' , n'utilisez pas str.contains . Vérifiez plutôt l'égalité et utilisez value_counts code> sur les valeurs que vous souhaitez compter:
import re
s = pd.Series(['HS+P+SD', 'AB+CD+EF'])
s.str.contains('HS+P+SD').sum() # 0
s.str.contains('HS+P+SD', regex=False).sum() # 1
s.str.contains(re.escape('HS+P+SD')).sum() # 1
s.str.contains('HS\+P\+SD').sum() # 1
Ou pour tous les comptes, utilisez simplement df ['class' ] .value_counts () .
Sinon, s.value_counts () devrait s'en occuper pour vous.
@piRSquared, j'y ai pensé, mais les données d'OP ont P + SD et HS + P + SD , donc ils veulent peut-être rechercher le premier pour inclure le second.
Essayez :
print(len(split_df[split_df["class"].str == 'HS+P+SD']))
Cela fonctionnait aussi bien, regex voyait fondamentalement + comme un signe spécial. Merci pour l'aide :)
Une boucle for simple avec in fonctionnera également
df=pd.concat([df]*100)
%timeit df['class'].str.contains('HS+P+SD', regex=False).sum()
1000 loops, best of 3: 410 µs per loop
%timeit sum(['HS+P+SD' in x for x in df['class']])
10000 loops, best of 3: 123 µs per loop
À propos du timing (si vous voulez vérifier ceci lien )
sum(['HS+P+SD' in x for x in df['class']])
J'ai changé le + pour une barre oblique inverse (/). Cela semble avoir résolu mon problème de comptage, pourquoi + interfère-t-il avec cela?