Pandas:根据百分位条件过滤数据框
Pandas: filter data frame based on percentile condition
我有一个数据框 df
,其中包含一些按页面浏览量 (PV) 排名的基本网络统计数据:
URL PVs
1 1500
2 1200
3 900
4 700
:
100 25
我正在尝试过滤和计算贡献不同百分比页面浏览量 (PV) 的 URL 的数量。比如说,我想知道有多少以及哪些曾经的 URL 带来了 90%(或 10%)的 PV。
我计算了百分位数:
df.quantile(np.linspace(.1, 1, 9, 0))
而且我知道我可以像这样遍历行(所以我可以总结它们):
for index, row in df.iterrows():
print row['PVs']
但我不知道如何在达到某个阈值时停止。感谢您的帮助!
我认为您需要按条件计算 sum
个 True
个值:
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
考虑 url 系列
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
作为值。因为是升序排列,所以我们可以进行累加求和,把你要找的断点处的item的位置都取出来。
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
我有一个数据框 df
,其中包含一些按页面浏览量 (PV) 排名的基本网络统计数据:
URL PVs
1 1500
2 1200
3 900
4 700
:
100 25
我正在尝试过滤和计算贡献不同百分比页面浏览量 (PV) 的 URL 的数量。比如说,我想知道有多少以及哪些曾经的 URL 带来了 90%(或 10%)的 PV。
我计算了百分位数:
df.quantile(np.linspace(.1, 1, 9, 0))
而且我知道我可以像这样遍历行(所以我可以总结它们):
for index, row in df.iterrows():
print row['PVs']
但我不知道如何在达到某个阈值时停止。感谢您的帮助!
我认为您需要按条件计算 sum
个 True
个值:
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
考虑 url 系列
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
作为值。因为是升序排列,所以我们可以进行累加求和,把你要找的断点处的item的位置都取出来。
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