样本过滤条件:-
x y z
1 2 1
1 3 2
1 2 5
1 3 1
现在我想从给定数据中过滤上述指定条件。 为此,我需要一个通用函数,即该函数不仅适用于上述指定的过滤器,还应该适用于所有过滤器。
我知道如何在python中为多个条件手动过滤数据。
我认为可能需要泛型函数两个参数,一个是数据,另一个是过滤条件。
但是我找不到写通用函数来过滤数据的逻辑。
任何人都可以帮助我解决。
谢谢。
答案 0 :(得分:2)
您可以先创建conditions
,然后再创建np.logical_and.reduce
的列表:
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
检查每行所有True
:
m1 = pd.concat([x1, y2, z1], axis=1).all(axis=1)
m2 = pd.concat([x1, y3, z1], axis=1).all(axis=1)
编辑:
如果可能,请定义列名称以及要在字典中进行过滤的值:
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的另一种方法:
df1 = pd.DataFrame([d1]).merge(df)
编辑:
对于一般解决方案,可以将文件的每个值解析为元组并使用operators:
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)]]
现在按列表的第一个值-文件的第一行进行过滤:
m = np.logical_and.reduce([ops[j](df[i], k) for i, j, k in L[0]])
print (m)
[False False True False]
答案 1 :(得分:1)
由于只有一个数字dtype
,因此可以使用基础的NumPy数组:
res = df[(df.values == [1, 2, 1]).all(1)]
print(res)
x y z
0 1 2 1
对于具有list
输入的通用函数:
def filter_df(df, L):
return df[(df.values == L).all(1)]
res = filter_df(df, [1, 2, 1])
如果您需要字典输入:
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})
答案 2 :(得分:1)
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)