首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >熊猫数据过滤的通用函数

熊猫数据过滤的通用函数
EN

Stack Overflow用户
提问于 2018-10-02 10:52:08
回答 3查看 1.9K关注 0票数 2

样本过滤条件:-

数据

代码语言:javascript
运行
复制
x  y  z 
1  2  1
1  3  2
1  2  5
1  3  1

现在,我希望从给定的数据中筛选上述指定的条件。为此,我需要一个泛型函数,也就是说,该函数应该适用于任何过滤器,而不仅仅是上面指定的过滤器。

我知道如何为不止一个条件手动过滤python中的数据。

我认为泛型函数可能需要两个参数,一个是数据,另一个是过滤条件。

但是我无法找到编写泛型函数来过滤数据的逻辑。

好心的任何人都能帮我解决。

提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-10-03 09:37:25

代码语言:javascript
运行
复制
def filter_function(df,filter_df):
  lvl_=list()
  lvl=list()
  vlv=list()
  df1=pd.DataFrame()
  n=filter_df.apply(lambda x: x.tolist(), axis=1)
  for i in range(0,len(n)):
      for j in range(0,len(n[i])):
          if i==0:
             lvl_.append(n[i][j].split('==')[0])
          lvl.append(n[i][j].split('==')[1])
          if len(lvl)==len(n[i]):
             vlv.append(lvl)
             lvl=list()
  final_df=df[lvl_]
  for k in range(0,len(vlv)):
      df1=df1.append(final_df[final_df.isin(vlv[k])].dropna())
  return(df1)

filter_function(df,filter_df)
票数 1
EN

Stack Overflow用户

发布于 2018-10-02 10:55:09

您可以创建conditions的列表,然后创建np.logical_and.reduce

代码语言:javascript
运行
复制
x1 = df.x==1
y2 = df.y==2 
z1 = df.z==1
y3 = df.y==3

m1 = np.logical_and.reduce([x1, y2, z1])
m2 = np.logical_and.reduce([x1, y3, z1])

concat所有掩码,并通过DataFrame.all检查每一行的所有Trues。

代码语言:javascript
运行
复制
m1 = pd.concat([x1, y2, z1], axis=1).all(axis=1)
m2 = pd.concat([x1, y3, z1], axis=1).all(axis=1)

编辑:

如果可能的话,用字典中筛选的值来定义列名:

代码语言:javascript
运行
复制
d1 = {'x':1, 'y':2, 'z':1}
d2 = {'x':1, 'y':3, 'z':1}

m1 = np.logical_and.reduce([df[k] == v for k, v in d1.items()])
m2 = np.logical_and.reduce([df[k] == v for k, v in d2.items()])

另一种使用merge从字典中创建的一行DataFrame方法:

代码语言:javascript
运行
复制
df1 = pd.DataFrame([d1]).merge(df)

编辑:

对于通用解决方案,可以将文件的每个值解析为元组并使用operators

代码语言:javascript
运行
复制
df1 = pd.DataFrame({0: ['x==1', 'x==1'], 1: ['y==2', 'y<=3'], 2: ['z!=1', 'z>1']})
print (df1)
      0     1     2
0  x==1  y==2  z!=1
1  x==1  y<=3   z>1


import operator, re

ops = {'>': operator.gt,
        '<': operator.lt,
       '>=': operator.ge,
       '<=': operator.le,
       '==': operator.eq,
        '!=': operator.ne}

#if numeric, parse to float, else not touch ()e.g. if string
def try_num(x):
    try:
        return float(x)
    except ValueError:
        return x

L = df1.to_dict('r')
#https://stackoverflow.com/q/52620865/2901002
rgx = re.compile(r'([<>=!]+)')
parsed = [[rgx.split(v) for v in d.values()] for d in L]
L = [[(x, op, try_num(y)) for x,op,y in ps] for ps in parsed]
print (L)
[[('x', '==', 1.0), ('y', '==', 2.0), ('z', '!=', 1.0)], 
 [('x', '==', 1.0), ('y', '<=', 3.0), ('z', '>', 1.0)]]

现在,通过列表的第一个值进行筛选--第一行文件:

代码语言:javascript
运行
复制
m = np.logical_and.reduce([ops[j](df[i], k) for i, j, k in L[0]])
print (m)
[False False  True False]
票数 2
EN

Stack Overflow用户

发布于 2018-10-02 12:53:42

由于只有一个数字dtype,所以可以使用基础NumPy数组:

代码语言:javascript
运行
复制
res = df[(df.values == [1, 2, 1]).all(1)]

print(res)

   x  y  z
0  1  2  1

对于具有list输入的泛型函数:

代码语言:javascript
运行
复制
def filter_df(df, L):
    return df[(df.values == L).all(1)]

res = filter_df(df, [1, 2, 1])

如果您需要字典输入:

代码语言:javascript
运行
复制
def filter_df(df, d):
    L = list(map(d.get, df))
    return df[(df.values == L).all(1)]

res = filter_df(df, {'x': 1, 'y': 2, 'z': 1})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52606908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档