通过比较列中的字典值来收集数据帧行

2024-06-10 23:20:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据框,其中有一列包含字典。 我的任务是比较dict中的前两个值,如果它们相等,那么我想收集整行。我不能显示我的任何代码,因为我真的不知道如何组织这个。但我将创建一个我的DF的小示例,以使情况更加清楚

import pandas as pd
test = pd.DataFrame({'one':['hello', 'there', 'every', 'body'],
       'two': ['a', 'b', 'c', 'd'],
       'dict': [{'composition': 12, 'process': 4, 'pathology': 4},
                {'food': 9, 'composition': 9, 'process': 6, 'other_meds': 3},
                {'process': 2},
                {'composition': 6, 'other_meds': 6, 'pathology': 2, 'process': 1}]})
test

因此,数据如下所示:

    one    two  dict
0   hello   a   {'composition': 12, 'process': 4, 'pathology': 4}
1   there   b   {'food': 9, 'composition': 9, 'process': 6, 'other_meds': 3}
2   every   c   {'process': 2}
3   body    d   {'composition': 6, 'other_meds': 6, 'pathology': 2, 'process': 1}

我的目标是收集到索引为1和3的新数据帧行,因为dict的两个前值是相同的'food': 9, 'composition': 9'composition': 6, 'other_meds': 6。索引号为0的行具有相同的值,但这并不有趣,因为它们不在第一和第二位置

我知道我们正在使用 loc iloc收集行。但是我不知道如何分配字典的条件。请帮忙


Tags: 数据testhello字典foodprocessonedict
3条回答

这个想法是你有一份口述的清单 由于钥匙不同,我们首先需要找出前两把钥匙(如果有的话)。接下来,我们获取我们学习的键并比较它们的值,如果它们匹配,我们将添加到列表中

dict_data = [{'composition': 12, 'process': 4, 'pathology': 4},
                     {'food': 9, 'composition': 9, 'process': 6, 'other_meds': 3},
                     {'process': 2},
                     {'process': 2, 'other_meds': 6},
                     {'composition': 6, 'other_meds': 6, 'pathology': 2, 'process': 1}]
new_list = []
for item in dict_data:
    val_keys = list(item.keys())
    if len(val_keys) >= 2 and item[val_keys[0]] == item[val_keys[1]]:
        new_list.append(item)
        print(item)

你可以做:

import pandas as pd

test = pd.DataFrame({'one': ['hello', 'there', 'every', 'body'],
                     'two': ['a', 'b', 'c', 'd'],
                     'dict': [{'composition': 12, 'process': 4, 'pathology': 4},
                              {'food': 9, 'composition': 9, 'process': 6, 'other_meds': 3},
                              {'process': 2},
                              {'composition': 6, 'other_meds': 6, 'pathology': 2, 'process': 1}]})


def equal_values(d):
    try:
        # extract first and second value
        first, second, *_ = d.values()
        return first == second
    except ValueError:
        return False  # if there are not two values


res = test[test['dict'].apply(equal_values)]
print(res)

输出

     one two                                               dict
1  there   b  {'food': 9, 'composition': 9, 'process': 6, 'o...
3   body   d  {'composition': 6, 'other_meds': 6, 'pathology...

符号:

first, second, *_ = d.values()

被称为extended iterable unpacking,请参见此answer以获得广泛的解释,而此post是入门教程

上面的特殊情况意味着取第一个,第二个忽略values中剩余的(*_

In [2]: import pandas as pd
   ...: test = pd.DataFrame({'one':['hello', 'there', 'every', 'body'],
   ...:        'two': ['a', 'b', 'c', 'd'],
   ...:        'dict': [{'composition': 12, 'process': 4, 'pathology': 4},
   ...:                 {'food': 9, 'composition': 9, 'process': 6, 'other_meds': 3},
   ...:                 {'process': 2},
   ...:                 {'composition': 6, 'other_meds': 6, 'pathology': 2, 'process': 1}]})
   ...: test
Out[2]: 
     one two                                               dict
0  hello   a  {'composition': 12, 'process': 4, 'pathology': 4}
1  there   b  {'food': 9, 'composition': 9, 'process': 6, 'o...
2  every   c                                     {'process': 2}
3   body   d  {'composition': 6, 'other_meds': 6, 'pathology...

In [3]: new_df = test[test.dict.apply(lambda x: list(x.values())[0] == list(x.values())[1] if len(x) > 1 else None) == True]
   ...: new_df
Out[3]: 
     one two                                               dict
1  there   b  {'food': 9, 'composition': 9, 'process': 6, 'o...
3   body   d  {'composition': 6, 'other_meds': 6, 'pathology...

相关问题 更多 >