Pandas:基于百分位条件过滤数据框

3

我有一个数据框df,其中包含一些基本的网站统计信息,按页面浏览量(PV)排名:

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

我正在尝试过滤和计算不同百分比页面浏览量(PV)的URL数量。比如说,我想知道有多少个URL以及哪些URL带来了90%(或10%)的PV。

我已经计算了百分位数:

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

我知道我可以像这样遍历行(所以我可以将它们加起来):
for index, row in df.iterrows():
    print row['PVs']

但我无法想象如何在达到一定阈值时停止。感谢您的帮助!

2个回答

7

我认为您需要根据条件计算True值的sum

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

如果需要统计所有分位数的数量:

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
我可能会针对稍微不同的任务使用这两个答案,但是这个答案正是我所需要的。像往常一样,谢谢! - aviss

3
考虑以下一系列网址。
s = pd.Series(np.random.randint(100, size=10000), name='URL')

使用pd.Series.value_counts函数获取计数列表,并使用normalize=True选项。另外,确保使用ascending=True进行升序排序。
vc = s.value_counts(normalize=True, ascending=True)

vc现在是一个序列,其索引是URL,值是规范化的counts。由于它是按升序排序的,我们可以执行累积求和并取出您要查找的断点处项目的位置。

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')

我们可以观察结果。
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
如果ascending=True 会减慢速度,我们可以跳过它,因为后面的.cumsum()保证了排序的性质。 - Divakar
@Divakar 绝对正确。在我的测试示例中,我将vc创建为OP数据的代理。无论哪种方式,cumsum部分都是相同的。 - piRSquared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接