Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用嵌套dict列表筛选数据帧_Python_Python 3.x_Pandas_Dataframe - Fatal编程技术网

Python 使用嵌套dict列表筛选数据帧

Python 使用嵌套dict列表筛选数据帧,python,python-3.x,pandas,dataframe,Python,Python 3.x,Pandas,Dataframe,示例数据,我有一个数据帧“df”: 身份证件 A. B 1. 嗯 狗 2. 嗯 猫 3. W 狗 IIUC,您希望从“筛选字典”创建一个数据帧,然后根据感兴趣的列合并以获得交集。要找到差异,您可以执行相同的操作,并使用id列从原始数据帧中删除相交的id 将熊猫作为pd导入 def filter_df(df,filter_dict,option='keep'): x=pd.concat([pd.merge(df,pd.DataFrame)([dic]), 怎么说, on=列表(dic.keys()

示例数据,我有一个数据帧“df”:

身份证件 A. B 1. 嗯 狗 2. 嗯 猫 3. W 狗
IIUC,您希望从“筛选字典”创建一个数据帧,然后根据感兴趣的列合并以获得交集。要找到差异,您可以执行相同的操作,并使用
id
列从原始数据帧中删除相交的id

将熊猫作为pd导入
def filter_df(df,filter_dict,option='keep'):
x=pd.concat([pd.merge(df,pd.DataFrame)([dic]),
怎么说,
on=列表(dic.keys())
对于过滤器中的dic,忽略索引=真)。删除重复项()
如果选项==“保留”:
返回x
elif选项==“排除”:
返回df[df[“id”].isin(x[“id”].values)==False]
其他:
NotImplementedError(f“选项{Option}未实现。请在“保留”和“排除”之间进行选择”。)
以下是测试用例:

data = {"id": [1,2,3], "a": ["HH", "HH", "W"], "b": ["DOG", "CAT", "DOG"]}
df = pd.DataFrame(data)

# test case 1
filter_dict_1 = [{'a': 'HH'}, {'a': 'W','b':'DOG'}]
df1 = filter_df(df, filter_dict_1, "keep")
print(df1)
#    id   a    b
# 0   1  HH  DOG
# 1   2  HH  CAT
# 2   3   W  DOG


# test case 2
filter_dict_2 = [{'a': 'HH', 'b': 'CAT'}]
df2 = filter_df(df, filter_dict_2, "exclude")
print(df2)
#   id   a    b
#0   1  HH  DOG
#2   3   W  DOG


# test case 3
filter_dict_3 = [{'a': 'HH', 'b':'CAT'}, {"a": 'HH'}]
df3 = filter_df(df, filter_dict_3, "exclude")
print(df3)
#   id  a    b
#2   3  W  DOG

data={“id”:[1,2,3],“a”:[“HH”,“HH”,“W”],“b”:[“DOG”,“CAT”,“DOG”]}
df=pd.DataFrame(数据)
#测试用例1
过滤条件1=[{'a':'HH'},{'a':'W','b':'DOG'}]
df1=过滤器df(df,过滤器dict 1,“保持”)
打印(df1)
##id a b
#0 1 HH狗
#1 2 HH猫
#2 3 W狗
#测试用例2
过滤器2=[{'a':'HH','b':'CAT'}]
df2=过滤器df(df,过滤器dict 2,“排除”)
打印(df2)
#身份证
#0 1 HH狗
#2 3 W狗
##测试用例3
过滤器3=[{'a':'HH','b':'CAT'},{'a':'HH'}]
df3=过滤器df(df,过滤器指令3,“排除”)
打印(df3)
#身份证
#2 3 W狗

如果您想要一个通用解决方案,您甚至不需要知道filter dict中指定的列,您可以使用双reduce:

从functools导入reduce
从运算符导入反转
def filter_df(df,filter_dict,option='keep'):
切片向量=reduce(λx,y:x | y,[reduce(λx,y:
x&y,[df[col]==col的val,el.items()中的val)
对于过滤器中的el(不适用)
如果选项==“保留”:
返回df.loc[切片向量]
elif选项==“排除”:
返回df.loc[反转(切片向量)]
其他:
NotImplementedError(f“选项{Option}未实现。请在“保留”和“排除”之间进行选择”。)
让我们将此应用于各种测试用例:

data = {"id": [1,2,3], "a": ["HH", "HH", "W"], "b": ["DOG", "CAT", "DOG"]}
df = pd.DataFrame(data)

# test case 1
filter_dict_1 = [{'a': 'HH'}, {'a': 'W','b':'DOG'}]
df1 = filter_df(df, filter_dict_1, "keep")
print(df1)
#    id   a    b
# 0   1  HH  DOG
# 1   2  HH  CAT
# 2   3   W  DOG


# test case 2
filter_dict_2 = [{'a': 'HH', 'b': 'CAT'}]
df2 = filter_df(df, filter_dict_2, "exclude")
print(df2)
#   id   a    b
#0   1  HH  DOG
#2   3   W  DOG


# test case 3
filter_dict_3 = [{'a': 'HH', 'b':'CAT'}, {"a": 'HH'}]
df3 = filter_df(df, filter_dict_3, "exclude")
print(df3)
#   id  a    b
#2   3  W  DOG


我们的想法是首先基于单个字典创建一个布尔向量。这些向量是通过将单个条件与
&
组合而成的,然后将这些向量与

组合成最终的过滤向量,您的预期输出是什么?@tomjn在问题中更新onlya=[{'a':'HH','b':'DOG'},{'a':'W','b':'DOG'}]应该是您的dict来实现此输出吗?@pythonic833我认为OP希望能够基于列“a”和“b”的值进行过滤。@NITINKOTHARI:正如Hamza usman ghani指出的,请更新您的字典。@NITINKOTHARI,因为在您更新的问题中,字典中的键数可能会有所不同,我会使用这个解决方案。更改逻辑运算符可以将逻辑从保留变为删除。(我将为您更新此答案中的示例)。非常感谢@PeterCurran和@pythonic833,这完全符合我在尝试提交代码时的要求。出现了一个pylint问题:E1130:一元操作数类型错误~:对象(无效的一元操作数类型)这一行:“return df.loc[~slice\u vector]”不想禁用它,你能告诉我怎么解决吗?@NITINKOTHARI不确定是什么原因造成的,但你可以尝试用
操作符替换
~slice\u vector
。反转(slice\u vector)
@NITINKOTHARI:这似乎是numpy和pandas结构中的一个已知问题,正如你所看到的,pylint正在抛出不必要的警告。在这里禁用它们是安全的。但我也更新了对Peter Curran建议的回答,这样就不会再发出警告了。我可以使用这种方法吗?我可以在df1的列上进行合并,类似于:int_df=pd.merge(df,df1,how='internal',on=df1.columns.values.tolist()),但是我将如何排除(如下面的答案中我们使用uranry Operator)@NITINKOTHARI,是的,我已经更新了答案,使用合并方法根据过滤器dict保留或排除。