【问题标题】:Pandas: evaluate two dataframes against each otherPandas:相互评估两个数据框
【发布时间】:2018-05-11 17:33:58
【问题描述】:

让我们想象一个记忆/回忆游戏。有些房间的桌子上摆满了巧克力和其他东西。您有 20 秒的时间查看每张桌子。稍后你会被问到你看到了什么。这给出了两个数据集。一个是表格的配置,另一个是你能记住的。任务是评估您正确回忆了哪些项目以及您不记得哪些项目。在这个任务中,我们不关心产品的品牌。只是类型。

这是两个房间的示例配置。

config = [
        {'room': 'room1', 'kind': 'chocolate', 'brand': 'Mars'},
        {'room': 'room1', 'kind': 'chocolate', 'brand': 'Mars'},
        {'room': 'room1', 'kind': 'chocolate', 'brand': 'Milka'},
        {'room': 'room1', 'kind': 'nuts', 'brand': 'Bahlsen'},
        {'room': 'room2', 'kind': 'chocolate', 'brand': 'Mars'},
        {'room': 'room2', 'kind': 'nuts', 'brand': 'Ültje'},
        {'room': 'room2', 'kind': 'nuts', 'brand': 'Bahlsen'}
        ]

import pandas as pd
df_config = pd.DataFrame(config).sort_values(['room'])
df_config

现在你有 20 秒的时间来记住时间。之后你会被问到你看到了什么。以下是你记得的:

recall = [
        {'room': 'room1', 'kind': 'chocolate'},
        {'room': 'room1', 'kind': 'chocolate'},
        {'room': 'room1', 'kind': 'nuts'},
        {'room': 'room2', 'kind': 'nuts'}
        ]

import pandas as pd
df_recall = pd.DataFrame(recall).sort_values(['room'])
df_recall

显然,您在 1 号房间看到了两根巧克力棒,因此您错过了第三根。对于房间 2,您错过了第二袋坚果。所以,评估结果会是这样的:

correct = [
        {'room': 'room1', 'kind': 'chocolate', 'brand': 'Mars', 'eval': 'correct'}, # first chocolate room1
        {'room': 'room1', 'kind': 'chocolate', 'brand': 'Mars', 'eval': 'correct'}, # second chocolate room1
        {'room': 'room1', 'kind': 'nuts', 'brand': 'Bahlsen', 'eval': 'correct'}, # first nuts room1
        {'room': 'room2', 'kind': 'nuts', 'brand': 'Ültje', 'eval': 'correct'}, # first nuts room2
        ]

incorrect = [
        {'room': 'room1', 'kind': 'chocolate', 'brand': 'Milka', 'eval': 'incorrect'}, # third chocolate room1 not recalled
        {'room': 'room2', 'kind': 'chocolate', 'brand': 'Mars', 'eval': 'incorrect'}, # first chocolate room2 not recalled
        {'room': 'room2', 'kind': 'nuts', 'brand': 'Bahlsen', 'eval': 'incorrect'} # second nuts room2 not recalled
        ]

我正在考虑根据房间合并两个数据集,然后按房间分组并评估每个组。通过迭代组或使用df.groupy(['room']).apply(my_function)。问题是,合并为每个房间创建了一个相当大的组,我不确定如何评估它。

df = pd.merge(df_config, df_recall, on='room', suffixes=('', '_recall'))

欢迎提出任何想法!

谢谢

【问题讨论】:

    标签: python pandas join dataframe merge


    【解决方案1】:

    我认为您需要每个 roomskind by cumcount 的唯一值的帮助列。然后将列添加到参数on 并指定左连接:

    df_config['g'] = df_config.groupby(['room','kind']).cumcount()
    df_recall['g'] = df_recall.groupby(['room','kind']).cumcount()
    
    df = pd.merge(df_config, df_recall, on=['room', 'g'], suffixes=('', '_recall'), how='left')
    print (df)
         brand       kind   room  g kind_recall
    0     Mars  chocolate  room1  0   chocolate
    1     Mars  chocolate  room1  0        nuts
    2     Mars  chocolate  room1  1   chocolate
    3    Milka  chocolate  room1  2         NaN
    4  Bahlsen       nuts  room1  0   chocolate
    5  Bahlsen       nuts  room1  0        nuts
    6     Mars  chocolate  room2  0        nuts
    7    Ültje       nuts  room2  0        nuts
    8  Bahlsen       nuts  room2  1         NaN
    

    【讨论】:

    • 最后只评估 kind 与 kind_recall?您的解决方案中的问题是,对于 room1,Bahlsen 坚果在 kind_recall 列中是 NaN,即使该人已正确记住它们。
    • df_config.groupby(['room', 'type']).cumcount() 呢?
    • 还有一件事:对于 room2,第一行显示巧克力与坚果。但实际上巧克力应该是 NaN,因为这家伙在 room2 中没有看到任何巧克力,而只是坚果。解决该问题的一种方法是将 df_recall 与 df_config 的所有唯一值类型一起加入。然后nuts 为1,chocolate 为0,合并将产生另一个结果。但是该怎么做呢?
    • 我稍微修改了你的代码。首先,我创建了 df_recall.kind 列的副本,然后将“kind”列添加到现在为 ['room', 'g', 'kind'] 的合并中。因此,合并结果的评估更容易,因为它是按产品种类自动排序/分组的。评估是: if row['kind'] == row['kind_seen']: return 'correct' elif row['kind_seen'] is np.NaN: return 'missed' elif row['kind'] != row ['kind_seen']:返回'忽略'
    猜你喜欢
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 2015-10-17
    相关资源
    最近更新 更多