2017-07-11 1 views
2

J'ai une trame de données df avec quelques stats web de base selon leur indice de vues (PVs):Pandas: cadre de données de filtre basé sur la condition percentile

URL PVs 
1 1500 
2 1200 
3 900 
4 700 
: 
100 25 

Je suis en train de filtrer et compter le nombre d'URL qui contribuent percentile différent des pages vues (PVs). Dites, je veux savoir combien et quelle URL une fois apporté 90% de PV (ou 10%).

I calculé centiles:

df.quantile(np.linspace(.1, 1, 9, 0)) 

Et je sais que je peux itérer des lignes comme celle-ci (donc je peux les résumer):

for index, row in df.iterrows(): 
    print row['PVs'] 

Mais je ne peux pas comprendre comment arrêter quand un certain seuil est atteint. Appréciera votre aide!

Répondre

3

Je pense que vous avez besoin besoin pour le nombre sum de True valeurs par des conditions:

a = (df['PVs'] > df['PVs'].quantile(0.9)).sum() 
print (a) 
1 
df1 = df[df['PVs'] > df['PVs'].quantile(0.9)] 
print (df1) 
    URL PVs 
0 1 1500 

a = (df['PVs'] < df['PVs'].quantile(0.1)).sum() 
print (a) 
1 
df1 = df[df['PVs'] < df['PVs'].quantile(0.1)] 
print (df1) 
    URL PVs 
4 100 25 

Et si besoin compte de tous les quantiles:

df1 = df.groupby(pd.qcut(df['PVs'], 10)).size() 
print (df1) 
PVs 
(24.999, 295.0]  1 
(295.0, 565.0]  0 
(565.0, 740.0]  1 
(740.0, 820.0]  0 
(820.0, 900.0]  1 
(900.0, 1020.0]  0 
(1020.0, 1140.0] 0 
(1140.0, 1260.0] 1 
(1260.0, 1380.0] 0 
(1380.0, 1500.0] 1 
dtype: int64 
+1

Je vais probablement utiliser les réponses pour des tâches légèrement différentes, mais cette réponse était exactement ce que je avais besoin. Merci comme d'habitude! – aviss

+0

Glad peut vous aider! Et merci. – jezrael

3

Tenir compte de la série de urls

s = pd.Series(np.random.randint(100, size=10000), name='URL') 

Obtenir une liste de comptes en utilisant pd.Series.value_counts et utilisez l'option normalize=True. Aussi, assurez-vous de trier par ordre croissant avec ascending=True

vc = s.value_counts(normalize=True, ascending=True) 

vc est maintenant une série avec URL s dans l'indice et counts normalisé comme les valeurs. Parce qu'il est trié par ordre croissant, nous pouvons effectuer une somme cumulative et arracher les positions des objets aux points de rupture que vous recherchez.

a = vc.cumsum().searchsorted(np.linspace(.1, 1, 9, 0)) 

vc.index[a] 

Int64Index([64, 40, 20, 18, 9, 45, 67, 30, 77], dtype='int64') 

Nous pouvons observer les résultats

a = vc.cumsum().searchsorted(np.linspace(.1, 1, 9, 0)) 
pd.concat([vc.cumsum().iloc[a], vc.iloc[a]], axis=1, keys=['Cumsum', 'Normalized']) 

    Cumsum Normalized 
64 0.1075  0.0089 
40 0.2083  0.0094 
20 0.3036  0.0096 
18 0.4010  0.0099 
9 0.5010  0.0101 
45 0.6032  0.0103 
67 0.7084  0.0106 
30 0.8049  0.0108 
77 0.9053  0.0114 
+1

Si 'ascending = True' ralentit, nous pouvons l'ignorer, car le' .cumsum() 'plus récent garantit la nature triée. – Divakar

+0

@Divakar absolument correct. Dans mon exemple de test, je crée 'vc' en tant que proxy pour les données d'OP. La partie «cumsum» est la même dans les deux cas. – piRSquared