如何根据“ isin”的结果将一列从一个数据框组合到另一列?

时间:2019-05-07 14:41:29

标签: python pandas

我有两个XLS工作表,我已将它们读入两个数据帧。我想找到两者之间的交集,其中一个df列的内容包含在另一df中的特定列中。然后从该交集创建一个新的df,其中包含交集以及这些df之一中特定列的值。

我无法弄清楚Pandas中的什么功能可以使该交叉点起作用,并包括来自附加列的数据。

这就是我想要得到的交叉点:

import pandas as pd
test_file = '/Users/Bill/Box Sync/Documents/Jupyter/test_data.xlsx'
# read in the xls sheets
prj_df = pd.read_excel(test_file, sheet_name = 'Sheet1')
opp_df = pd.read_excel(test_file, sheet_name = 'Sheet2')
# intersect the sheets
report_df = opp_df[opp_df['opp'].isin(prj_df['opp numbers'])]

...但是您将在下面看到,report_df仅包含“ opp”和“ opp数字”的内容完全匹配的行。在字符串中查找字符串时,我需要更类似于Python的“ in”关键字。

以下是一些测试数据:

prj_df:

   Project            opp numbers          URL
0  Project 1 title    ab-cdefg;12-34567    http://1.2.3.4/abc
1  project 2 title    MJ-98733             http://1.2.3.4/UJUJUJUJ
2  Project 3 title    No code              http://1.2.3.4/99a
3  Project A title    01-PKL23             http://1.2.3.4/azzz
4  project B title    44-0098876           http://test.133
5  project c title    342-0981;98-09913    http://2.3.4.5/iiihh
6  project 99 title   25-AAAJJ12;99-49494  http://1.2.3.4/ghhi
7  project 303 title  77-AUDIJJ            http://1.2.3.4/def

opp_df:

0  opp        product     price
1  98-09913   widget1     123.55
2  66-99999   widget2     44.99
3  AB-DEFFF1  widget3     2345.5
4  01-PKL23   item a      9990
5  77-AUDIJJ  item b      84.56
6  KK-KIEW89  product 99  22.99
7  WE-24422   name 123    1.99
8  12-34567   stuff 1     395.5

report_df:

   opp        product     price
3  01-PKL23   item a      9990.00
4  77-AUDIJJ  item b      84.56

.....但是report_df中的数据不完整:我还需要显示第1行和第8行,因为这些行中的'opp'值也包含在prj_df中。

现在,除了正确设置交点外,我还想将prj_df的URL和Project列中的值添加到report_df的末尾。由于我一直在使用openpyxl库,因此我的大脑只需要遍历工作表/数据框并在prj_df中搜索值即可,而不是使用我已经做过的isin交集。

是否有办法a)使该交叉点工作,并且b)将Project和URL值拉入该相交的数据框中?

1 个答案:

答案 0 :(得分:0)

使用熊猫合并功能可以更轻松地完成此操作。但是要做到这一点,您首先必须使用this函数将值拆分为行。

之后,您可以执行inner merge

prj_df = explode_str(df, 'opp numbers', sep=';')
print(prj_df)

             Project opp numbers                      URL
0    Project 1 title    ab-cdefg       http://1.2.3.4/abc
0    Project 1 title    12-34567       http://1.2.3.4/abc
1    project 2 title    MJ-98733  http://1.2.3.4/UJUJUJUJ
2    Project 3 title     No code       http://1.2.3.4/99a
3    Project A title    01-PKL23      http://1.2.3.4/azzz
4    project B title  44-0098876          http://test.133
5    project c title    342-0981     http://2.3.4.5/iiihh
5    project c title    98-09913     http://2.3.4.5/iiihh
6   project 99 title  25-AAAJJ12      http://1.2.3.4/ghhi
6   project 99 title    99-49494      http://1.2.3.4/ghhi
7  project 303 title   77-AUDIJJ       http://1.2.3.4/def

现在我们可以合并:

report_df = opp_df.merge(prj_df[['opp numbers']], 
                         left_on='opp', 
                         right_on='opp numbers').drop('opp numbers', axis=1)

print(report_df)
         opp  product    price
0   98-09913  widget1   123.55
1   01-PKL23   item a  9990.00
2  77-AUDIJJ   item b    84.56
3   12-34567  stuff 1   395.50

链接答案中使用的功能

def explode_str(df, col, sep):
    s = df[col]
    i = np.arange(len(s)).repeat(s.str.count(sep) + 1)
    return df.iloc[i].assign(**{col: sep.join(s).split(sep)})