【问题标题】:Query/Filter a pandas df using a dict of lists使用列表字典查询/过滤 pandas df
【发布时间】:2023-02-06 15:15:19
【问题描述】:

我的问题

我有一个 dict d 可以由以下格式组成的不同长度:

d = {
  "foo": [
    50,
    100
  ],
  "bar": [
    5,
    10
  ]
}

其中键是列名,值是用于过滤 datframe df 的所述列的最小值和最大值的两个长度列表。因此,鉴于上面的输入,我想在 50-100 之间过滤 df.foo,在 5-10 之间过滤 df.bar

我试过的

当然,我可以像这样硬编码:

df.loc[(df.list(d.items())[0][0] > list(d.items())[0][1][0]) & (df.list(d.items())[0][0] < list(d.items())[0][1][1]) ...]

等等,但是键的数量(要过滤的列)可能会有所不同,而且这只是非常难看的代码。有没有更清洁/矢量化的方法来做到这一点?

语境

我正在构建一个 streamlit 应用程序,用户可以在其中在数据帧上创建 n min max 过滤器,上面列出的格式是 streamlit's slider 返回的格式

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    IIUC,一种使用pandas.Series.between的方法:

    # sample
    import numpy as np
    np.random.seed(1234)
    
    df = pd.DataFrame({"foo": np.random.random(10) * 100,
                       "bar": np.random.random(10) * 10})
    
             foo       bar
    0  19.151945  3.578173
    1  62.210877  5.009951
    2  43.772774  6.834629
    3  78.535858  7.127020
    4  77.997581  3.702508
    5  27.259261  5.611962
    6  27.646426  5.030832
    7  80.187218  0.137684
    8  95.813935  7.728266
    9  87.593263  8.826412
    

    代码:

    new_df = df[np.logical_and(*[df[k].between(*v) for k, v in d.items()])]
    print(new_df)
    

    输出:

             foo       bar
    1  62.210877  5.009951
    3  78.535858  7.127020
    8  95.813935  7.728266
    9  87.593263  8.826412
    

    【讨论】:

      猜你喜欢
      • 2016-06-27
      • 2015-12-22
      • 2021-09-05
      • 1970-01-01
      • 2019-12-31
      • 2016-02-14
      • 2019-07-26
      • 1970-01-01
      • 2022-08-03
      相关资源
      最近更新 更多