如何在python中根据特定条件使用第二个pandas数据框的索引在第一个pandas数据框中创建新列?

yvgpqqbh  于 2023-04-28  发布在  Python
关注(0)|答案(2)|浏览(109)

让我用一个简单的例子来描述这个问题。
假设我们创建了df1和df1如下:

df1 = pd.DataFrame({'month': [1, 4, 7, 10],
               'year': [2012, 2014, 2013, 2014],
               'sale': [55, 40, 84, 31]})
df2 = pd.DataFrame({'month1': [2,3,4,1, 4, 7, 10],
                   'year1': [2012,2012,2012,2012, 2014, 2013, 2014],
                   'sale1': [34,35,36,55, 40, 84, 31]})
df2.set_index(pd.Index([100, 200, 300, 411,444,415,416]))

现在df1和df2看起来像

month    year    sale
0   1   2012    55
1   4   2014    40
2   7   2013    84
3   10  2014    31

    month1  year1   sale1
100 2   2012    34
200 3   2012    35
300 4   2012    36
411 1   2012    55
444 4   2014    40
415 7   2013    84
416 10  2014    31

现在,对于df1的每一行,我们找到df2的索引,使得df1.month=df2.month1,df1.year=df2.year1,df1.sale=df2.sale1。对于df1的第一行,我们找到df2中的索引,即411。我们对df1中的所有值执行此操作,并在df1中创建一个存储此索引的新列
最终的df1看起来像这样:

month year    sale    index_result
0   1   2012    55  411
1   4   2014    40  444
2   7   2013    84  415
3   10  2014    31  416

这里
1.我们不能保证df2中只有一个唯一的索引与条件匹配。在这种情况下,我们只取第一个值。
1.两个dataframes之间的列名会不同(我在这里只使用了后缀1)。这不需要太多的关注,因为我可以用新的列名创建临时dataframes,以便列名匹配。但是两个dataframes都有多个其他列名。
由于我来自c++背景,我可以实现一个循环解决方案,但这将是非常低效的,因为在我的情况下,df1有数千行,df2有数百万行。
我正在寻找一个有效的解决方案,在时间方面。。我认为我有足够的内存在我的系统上,所以内存应该不是一个问题。
如果要求完整的解决方案是太多,我会很感激任何线索,可以引导我到一个有效的解决方案。
我在stackoverflow中找不到任何类似的查询。如果有人能指出一个重复的查询,那也会很有帮助。

uklbhaso

uklbhaso1#

一种方法是走pd.merge路线:

import pandas as pd

# I have added an additional duplicate row to df2 illustrate your first point
df1 = pd.DataFrame({'month': [1, 4, 7, 10],
               'year': [2012, 2014, 2013, 2014],
               'sale': [55, 40, 84, 31]})
df2 = pd.DataFrame({'month1': [2,3,4,1, 4, 7, 10, 1],
                   'year1': [2012,2012,2012,2012, 2014, 2013, 2014, 2012],
                   'sale1': [34,35,36,55, 40, 84, 31, 0]})
df2 = df2.set_index(pd.Index([100, 200, 300, 411,444,415,416, 500]))

df1 = (
    pd.merge(
        df1,
        df2.drop_duplicates(subset=["month1", "year1"]).reset_index(names="index_result"),
        left_on=["month", "year"],
        right_on=["month1", "year1"],
        how="left"
    )
    [["month", "year", "sale", "index_result"]]
)

输出:

month  year  sale  index_result
0      1  2012    55           411
1      4  2014    40           444
2      7  2013    84           415
3     10  2014    31           416

但是注意你要找的标签在df2中作为索引的一部分在这里有点不方便,我只是简单地将它们重置回df2,然后在最后选择它们。

nhhxz33t

nhhxz33t2#

您可以简单地执行以下操作:

df1['index_result'] = [df2.query('month1 == {} and year1 == {} and sale1 == {}'.format(row['month'], row['year'], row['sale'])).index[0] for _, row in df1.iterrows()]

也就是说

month year    sale    index_result
0   1   2012    55  411
1   4   2014    40  444
2   7   2013    84  415
3   10  2014    31  416

相关问题