如果数据框列值匹配字典键,检查不同的列是不是匹配字典值

Posted

技术标签:

【中文标题】如果数据框列值匹配字典键,检查不同的列是不是匹配字典值【英文标题】:If dataframe column value matches dictionary key, check if different column matches dictionary value如果数据框列值匹配字典键,检查不同的列是否匹配字典值 【发布时间】:2020-09-10 19:40:40 【问题描述】:

我有一个包含 2 列感兴趣的数据框。两者都充满了字符串。我还有一个映射键值对字典,它们也是字符串。我正在使用字典的键通过第一列过滤数据框,仅针对字典中的那些键。

最终目标是查找数据框的第一列,将其与字典中的键匹配,然后确认第 2 列的值与字典中的值匹配。

感兴趣的键上的过滤数据框按预期工作,所以我留下了一个两列的数据框,其中只有字典中存在的列键。过滤后的数据帧可以是几行到几千行不等,但字典的长度是静态的。

最终输出应该是一个数据框,其内容显示过滤后的数据框的行,其中第二列的值与字典的值不匹配。

pairs = 'red': 'apple', 'blue': 'blueberry', 'yellow':'banana'
filtered_data = 'Color':['red', 'blue'], 'Fruit':['appl','blueberry']
filtered_df = pd.DataFrame(filtered_data)

#so the filtered_df would resemble
Color     Fruit
red       appl
blue      blueberry

for row in filtered_df.iterrows():
   for k,v in pairs.items():
       #Here's where I'd like to check the value of column 1, find it in the dict then if the 
       #values dont match between col 2 in the df and the dict, append the mismatched row to a 
       #new df.
       if row['Color'] == k:
          new_df.append(row).where(row['Fruit'] != v)

我确定我需要第一个 for 循环中的行的索引,但我不确定如何格式化嵌套循环结构的其余部分。

理想情况下,当我在这种情况下导出我的new_df 数据框时,它将有 1 行的颜色列为红色,水果列为 appl,因为它与类似于下面的字典不匹配。

Color   Fruit
red     appl

【问题讨论】:

你能提供预期的数据框吗? 我不太确定,但你可以试试df[df['Color'].map(pairs) != df['Fruit']] 看看是否适合你?如果没有 - 你能解释一下它应该给你什么吗? 刚刚更新了我希望得到的 df 的样子 @JonClements 解决方案工作正常 【参考方案1】:
color_fruit = pd.Series((tuple(x) for x in filtered_df.values), index=filtered_df.index)
result = filtered_df[~color_fruit.isin(pairs.items())]

解释:

在第一行中,我们从原始数据帧的列中创建一系列元组(对),具有相同的索引。

然后我们用它来过滤原始数据框,只选择不 (~) 满足条件的行是 pairs 字典中 (key, value) 对的成员 (.isin())。

【讨论】:

除了cmets中提供的建议外,这也有助于解决上述问题【参考方案2】:

就我个人而言,我会从您的 pairs 字典创建一个数据框并进行左反连接,这将只留下您左侧数据框中与 pairs 字典不匹配的匹配项。

df1 = pd.DataFrame.from_dict(pairs, orient="index", columns=["Fruit"])\
                        .rename_axis("Color")\
                        .reset_index() 

final = pd.merge(filtered_df,df1,on=['Fruit','Color'],how='outer',indicator=True)\
                    .query("_merge == 'left_only'").drop('_merge',axis=1)

print(final)

 Color Fruit
0   red  appl

【讨论】:

Smart,将 dict 转换为 df 并利用合并逻辑似乎要简单得多。我会试试的。

以上是关于如果数据框列值匹配字典键,检查不同的列是不是匹配字典值的主要内容,如果未能解决你的问题,请参考以下文章

如何在循环中读取数据框列值并检查每列的数据类型

将具有多个键的 Python 字典映射到具有多个匹配键的列的数据框中

我如何将两个数据框列值作为键传递给2键到一个值字典,然后将结果传递到另一列?

将字典列表的 Python 数据框列转换为具有单个元素的列

使用部分字符串匹配将数据框中的列替换为另一个数据框列

将字典转换为数据框,键作为列名,键值作为数据框的列值