【问题标题】:Pandas: filter data frame based on percentile conditionPandas:根据百分位条件过滤数据框
【发布时间】:2017-12-15 21:42:56
【问题描述】:

我有一个数据框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']

但我无法弄清楚当达到某个阈值时如何停止。感谢您的帮助!

【问题讨论】:

    标签: python-2.7 pandas percentile


    【解决方案1】:

    考虑一系列网址

    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 现在是一个在索引中包含URLs 并标准化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
    

    【讨论】:

    • 如果ascending=True 拖慢了它,我们可以跳过它,因为后面的.cumsum() 保证了排序的性质。
    • @Divakar 绝对正确。在我的测试示例中,我创建 vc 作为 OP 数据的代理。无论哪种方式,cumsum 部分都是相同的。
    【解决方案2】:

    我认为您需要按条件计算 sumTrue 值:

    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
    

    【讨论】:

    • 我可能会将这两个答案用于稍微不同的任务,但这个答案正是我所需要的。像往常一样谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 2019-08-14
    • 2015-09-26
    相关资源
    最近更新 更多