【问题标题】:Filter pandas dataframe by quantile based on the value of another column根据另一列的值按分位数过滤熊猫数据框
【发布时间】:2021-02-27 19:41:14
【问题描述】:

我在将某些过滤器应用到我的数据集时遇到问题,我不知道该怎么做。我有一个包含 7 列的数据框。一列 participant_id 标识参与者(每个参与者唯一的数值),第二列指示每个参与者所属的组 (group),第三列 trial 标识试验(每个参与者参与者对一项任务执行多次试验)和四列var 1var 2var 3var 4(对应于每个试验记录的四个变量的数值)。有参与者进行了 100 多次试验,也有参与者进行了大约 50 次试验。

简短示例:

       participant_id        group         trial       var1        var2       var3        var4        
         189                   A             1      -0.231046    0.245615  -0.581238   -0.593562  
         189                   A             2      -0.231046    0.245615  -0.581238   -0.593562
         189                   A             3      -0.231046    0.245615  -0.581238   -0.593562
         189                   A             4      -0.231046    0.245615  -0.581238   -0.593562
         345                   B             1         NaN       0.245615  -0.581238   -0.593562
         345                   B            378     -0.231046    0.245615  -0.581238   -0.593562
         227                   A             1      -0.231046    0.245615  -0.581238   -0.593562
         227                   A             1      -0.231046    0.245615  -0.581238   -0.593562
         227                   A             2      -0.231046    0.245615  -0.581238   -0.593562
         432                   B            517     -0.231046    0.245615     NaN      -0.593562
         432                   B             2      -0.231046    0.245615     NaN      -0.593562
         432                   B            333     -0.231046    0.245615  -0.581238   -0.593562

以 4 名参与者为例。请注意,试用号不是唯一的,因为两个不同的参与者可以有一个试用“1”,而同一个参与者也可以有多个试用“1”。 (不要介意每行的 var 列的值都是相同的,在实际数据集中并非如此)。真正的数据集是 10000 行。

我需要做的是根据 var1。我正在考虑使用 pandas .quantile(n) 函数,但我不知道如何告诉它应该分别分析每个参与者,而不是整行来获取分位数。

感谢任何帮助。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:
    • 组上的apply() 传递每个组的Dataframe
    • 提供了使用lambda 以及独立函数的示例
    • 上述示例数据没有任何功能可以证明其功能
    df = pd.read_csv(io.StringIO("""       participant_id        group         trial       var1        var2       var3        var4        
             189                   A             1      -0.231046    0.245615  -0.581238   -0.593562  
             189                   A             2      -0.231046    0.245615  -0.581238   -0.593562
             189                   A             3      -0.231046    0.245615  -0.581238   -0.593562
             189                   A             4      -0.231046    0.245615  -0.581238   -0.593562
             345                   B             1         NaN       0.245615  -0.581238   -0.593562
             345                   B            378     -0.231046    0.245615  -0.581238   -0.593562
             227                   A             1      -0.231046    0.245615  -0.581238   -0.593562
             227                   A             1      -0.231046    0.245615  -0.581238   -0.593562
             227                   A             2      -0.231046    0.245615  -0.581238   -0.593562
             432                   B            517     -0.231046    0.245615     NaN      -0.593562
             432                   B             2      -0.231046    0.245615     NaN      -0.593562
             432                   B            333     -0.231046    0.245615  -0.581238   -0.593562
    """), sep="\s+")
    
    def f(d):
        return d.quantile()
    
    df.groupby("participant_id", as_index=False).apply(f)
    df.groupby("participant_id", as_index=False).apply(lambda d: d.quantile())
    
    

    更新

    • 问题是如何在组内利用 pandas 的分位数功能,第一部分回答了
    • 这专门展示了如何使用这种方法过滤到分位数内的行
    • 为演示目的生成了一个形状相同的随机数据集
    # generate a useful dataset to analyse...
    s = 100
    df = pd.DataFrame({"participant_id":np.random.choice([189,227,345,432],s),
                 "trial":np.random.randint(1,6,s),
                 "group":np.random.choice(["A","B"],s),
                  "var1":np.random.rand(s),
                  "var2":np.random.rand(s),
                  "var3":np.random.rand(s),
                  "var4":np.random.rand(s),
                 })
    
    # split into 10 quantile bins and take 0th bin
    # split into 10 quantile bins and take 0th bin
    df.groupby("participant_id").apply(
        lambda d: d.loc[pd.qcut(d.var1, q=10, retbins=False, labels=False).le(0)]).droplevel(0)
    
    
    
    participant_id trial group var1 var2 var3 var4
    13 189 3 A 0.0273875 0.87134 0.555792 0.67094
    85 189 1 A 0.0106758 0.352578 0.481009 0.910989
    91 189 4 A 0.00835706 0.644102 0.990459 0.816669
    4 227 5 B 0.10132 0.870446 0.389972 0.313782
    71 227 4 B 0.0221867 0.17566 0.659024 0.910838
    74 227 1 A 0.0762526 0.458995 0.492384 0.556408
    28 345 5 A 0.130674 0.0336628 0.0429884 0.799307
    82 345 1 B 0.234522 0.371108 0.451911 0.54528
    93 345 4 B 0.272915 0.594262 0.392285 0.56374
    16 432 2 B 0.0403964 0.880132 0.45438 0.0466626
    18 432 5 A 0.0884496 0.304541 0.969059 0.949315
    22 432 2 B 0.115796 0.0371306 0.631284 0.537881
    55 432 2 B 0.102859 0.0416843 0.761466 0.56438

    【讨论】:

    • 对不起,也许我没有正确表达自己(或者我做错了什么),但如果我没记错的话,那些方法返回分位数值,我想要的是所有的值超过该值
    • 已更新答案 - 我理解您的问题是如何在数据组中使用这些类型的功能。已经更进一步展示了如何使用来过滤分位数内的数据。显然你可以调整垃圾箱和你想要的垃圾箱
    猜你喜欢
    • 2014-12-27
    • 2020-08-08
    • 1970-01-01
    • 2016-08-31
    • 2021-12-01
    • 2016-11-16
    • 2020-08-16
    • 1970-01-01
    • 2022-12-06
    相关资源
    最近更新 更多