当前位置: 首页 > 面试题库 >

动态过滤pandas数据框

昝阳嘉
2023-03-14
问题内容

我正在尝试使用三列阈值过滤pandas数据框

import pandas as pd
df = pd.DataFrame({"A" : [6, 2, 10, -5, 3],
                   "B" : [2, 5, 3, 2, 6],
                   "C" : [-5, 2, 1, 8, 2]})
df = df.loc[(df.A > 0) & (df.B > 2) & (df.C > -1)].reset_index(drop = True)

df
    A  B  C
0   2  5  2
1  10  3  1
2   3  6  2

但是,我想在一个函数中执行此操作,在字典中将列名及其阈值提供给我。这是我的第一次尝试,可以。本质上,我将过滤器放入cond变量中,然后运行它:

df = pd.DataFrame({"A" : [6, 2, 10, -5, 3],
                   "B" : [2, 5, 3, 2, 6],
                   "C" : [-5, 2, 1, 8, 2]})
limits_dic = {"A" : 0, "B" : 2, "C" : -1}
cond = "df = df.loc["
for key in limits_dic.keys():
    cond += "(df." + key + " > " + str(limits_dic[key])+ ") & "
cond = cond[:-2] + "].reset_index(drop = True)"
exec(cond)
df
    A  B  C
0   2  5  2
1  10  3  1
2   3  6  2

现在,最后我将所有内容都放到了函数中,并且它停止了工作(也许exec函数不喜欢在函数中使用!):

df = pd.DataFrame({"A" : [6, 2, 10, -5, 3],
                   "B" : [2, 5, 3, 2, 6],
                   "C" : [-5, 2, 1, 8, 2]})
limits_dic = {"A" : 0, "B" : 2, "C" : -1}
def filtering(df, limits_dic):
    cond = "df = df.loc["
    for key in limits_dic.keys():
        cond += "(df." + key + " > " + str(limits_dic[key])+ ") & "
    cond = cond[:-2] + "].reset_index(drop = True)"
    exec(cond)
    return(df)

df = filtering(df, limits_dic)
df
    A  B  C
0   6  2 -5
1   2  5  2
2  10  3  1
3  -5  2  8
4   3  6  2

我知道exec函数在函数内部使用时的行为会有所不同,但不确定如何解决该问题。另外,我想知道在给定两个输入的情况下,必须有一种更优雅的方法来定义执行过滤的函数:1)df和2)limits_dic = {"A" : 0, "B" : 2, "C" : -1}。我对此表示感谢。


问题答案:

如果您尝试构建动态查询,则有更简单的方法。这是一个使用列表推导和的示例str.join

query = ' & '.join(['{}>{}'.format(k, v) for k, v in limits_dic.items()])

或者,将f-strings与python-3.6 +一起使用,

query = ' & '.join([f'{k}>{v}' for k, v in limits_dic.items()])



print(query)

'A>0 & C>-1 & B>2'

将查询字符串传递给df.query,这就是为了这个目的:

out = df.query(query)
print(out)

    A  B  C
1   2  5  2
2  10  3  1
4   3  6  2

如果我的列名包含空格或其他奇怪的字符怎么办?

从pandas 0.25起,您可以将列名包装在反引号中,这样可以正常工作:

query = ' & '.join([f'`{k}`>{v}' for k, v in limits_dic.items()])

有关更多信息,请参见此堆栈溢出文章。

df.eval如果要为查询获取布尔掩码,也可以使用它,然后在此之后索引将变得很简单:

mask = df.eval(query)
print(mask)

0    False
1     True
2     True
3    False
4     True
dtype: bool

out = df[mask]
print(out)

    A  B  C
1   2  5  2
2  10  3  1
4   3  6  2

字符串数据

如果您需要查询使用字符串数据的列,则上面的代码将需要进行一些修改。

考虑:

df = pd.DataFrame({'gender':list('MMMFFF'),
                   'height':[4,5,4,5,5,4],
                   'age':[70,80,90,40,2,3]})

print (df)
  gender  height  age
0      M       4   70
1      M       5   80
2      M       4   90
3      F       5   40
4      F       5    2
5      F       4    3

以及列,运算符和值的列表:

column = ['height', 'age', 'gender']
equal = ['>', '>', '==']
condition = [1.68, 20, 'F']

这里的适当修改是:

query = ' & '.join(f'{i} {j} {repr(k)}' for i, j, k in zip(column, equal, condition))
df.query(query)

   age gender  height
3   40      F       5

有关pd.eval()功能系列,其功能和使用案例的信息。



 类似资料:
  • 本文向大家介绍Pandas的数据过滤实现,包括了Pandas的数据过滤实现的使用技巧和注意事项,需要的朋友参考一下 作者|Amanda Iglesias Moreno 编译|VK 来源|Towards Datas Science 从数据帧中过滤数据是清理数据时最常见的操作之一。Pandas提供了一系列根据行和列的位置和标签选择数据的方法。此外,Pandas还允许你根据列类型获取数据子集,并使用布尔

  • 我有一个带有一列字符串值的pandas DataFrame。我需要根据部分字符串匹配来选择行。 类似于这个成语 返回布尔值。我熟悉的语法,但似乎找不到一种方法来处理部分字符串匹配,比如。

  • 问题内容: 我刚刚开始使用SQLAlchemy。我决定使用它,因为我在sqlite查询中间使用了很多字符串表达式。 所以,这就是我的问题。我的桌子上有很多设备,每个设备都有维护级别的日期。关键是用户可以选择他想在屏幕上看到的维护级别。因此,我应该为他选择的每种维护级别组合“调整”我的SQLAlchemmy。 例如,在原始SQLite中。 SELECT * WHERE(设备IN [])和m_leve

  • 问题内容: 我正在尝试使用作为df一部分的几个布尔变量来过滤df,但一直未能做到。 样本数据: C和D列的dtype是布尔值。我想仅使用C或D为True的行创建一个新的df(df1)。它看起来应该像这样: 我已经尝试过类似的事情,因为它无法处理布尔类型,因此会遇到问题: 有任何想法吗? 问题答案: In [82]: d Out[82]: A B C D 0 John Doe 45 True Fal

  • 永远不要信任外部输入。请在使用外部输入前进行过滤和验证。filter_var()和 filter_input() 函数可以过滤文本并对格式进行校验(例如 email 地址)。 外部输入可以是任何东西:$_GET 和 $_POST 等表单输入数据,$_SERVER 超全局变量中的某些值,还有通过 fopen('php://input', 'r') 得到的 HTTP 请求体。记住,外部输入的定义并不局

  • 主要内容:限制第一个和最后一个,其他过滤器Firebase提供了多种方式来过滤数据。 限制第一个和最后一个 下面我们来了解第一个和最后一个数据限制是什么。 方法返回从第一个开始向前的指定数量的项目。 方法返回从最后一个开始向前的指定数量的项目。 下面这个例子是展示如何工作的。 由于在数据库中只有三个运动员数据,这里将限制查询返回一个运动员数据。 示例 现在,参考下面的例子 - 控制台会记录第一个查询得到前两个运动员数据,第二个查询得到最后