首页 > 解决方案 > 使用 Python 提取和匹配处理多个数据帧的项目

问题描述

我有两个可以使用下面显示的代码创建的数据框

df1 = pd.DataFrame({'home':[1,np.nan,2,np.nan,3,4],
 'PERSONAL INFORMATION':['Study Number', 'Study ID','Age when interview 
 done', 'Derived using date of birth','Gender','ethnicity],
   'VARIABLE': 
['studyid','dummy','age_interview','dummy','gender','Chinese'],
    'Remarks':[2000000001,20005000001,4265453,0,4135376,2345678]})

在此处输入图像描述

 df2 = df2 = pd.DataFrame({'level_0': ['studyid','age_interview','gender','dobyear','ethderived','smoke','alcohol'],
 '0':['tmp001', 56,'Female',1950,'Chinese','No', 'Yes']})

在此处输入图像描述

目标

1) 我的目标是从df2的 'level_0'列中获取值,并在 df1 的'VARIABLE'列中查找它们以获取它们的 'Remarks'列值,前提是它满足以下条件

  a) 'Home' column of df1 should contain digits as part of their value( Ex: 1,2,3,4,B1.5,C1.9, D1.2 etc are all valid values for 'Home' column) 

2)我的目标与上述相同,但在这里我想从df2的“0”列中获取值并在 df1 的“个人信息”列中查找它们以获取它们的“备注”值,前提是它满足以下条件

  a) 'VARIABLE' column of df1 should contain 'dummy' as a value

对于上述两种情况,我编写了以下代码,但由于某种原因,我觉得它相当冗长/效率低下。应该有一些简单的方法来做到这一点。

情景 - 1

qconc_id = []
missed_items=[]
col_list=[]
for i in df7.index:
   ques = df7['level_0'][i]
   col_list.append(ques)
   try:
      qindex = int(df[df['VARIABLE']==ques].index[0]), 
                    df.columns.get_loc('VARIABLE')
    pos_qindex = qindex[0]
    ques_value = df['home '][pos_qindex]
    result = re.match(r"[A-Z]?[\d]?[\.]?[\d]+", ques_value)
    while result is None:
        pos_qindex = pos_qindex-1
        ques_value = df['home '][pos_qindex]
        result = re.match(r"[A-Z]?[\d]?[\.]?[\d]+", ques_value)
    qconc_id.append(df['Remarks'][pos_qindex])
    except:
        missed_items.append(ans)

情景 - 2

aconc_id = []
missed_items=[]
ans_list=[]
for i in df7.index:
    ans = df7[0][i]
    print("ans is ",ans)
    ans_list.append(ans)
    idx=0
    try:
        aindex = df[df['PERSONAL 
         INFORMATION'].str.contains(ans,case=False,regex=False)].index
         print(aindex)
         pos_aindex = aindex[idx]
         while (df['VARIABLE'][pos_aindex] !='dummy') and 
        (df['PERSONAL INFORMATION'].str.contains('Yes|No',regex=True) 
        [pos_aindex])==False):
             pos_aindex = aindex[idx+1]
         print("The value is ",df['Remarks'][pos_aindex])
         aconc_id.append(df['Remarks'][pos_aindex])
    except:
          print("Goes to Exception")
          aconc_id.append('0')
          missed_items.append(ans)

请注意这两点

a) 我使用了 while 循环,因为这些值可能会重复。例如,我们可能有一个匹配值为 'No' 但 df1['VARIABLE'] 可能不是虚拟的。因此,我在两种情况下都增加了 id 值,以查找下一次出现的“否”是否具有 VARIABLE 列的“虚拟”值。这同样适用于场景 1

b) 在“Notes”、“Nocase”中找到匹配项时,如何处理“No”等场景。正如您从我的代码中看到的那样,我正在使用正则表达式,但在这里仍然遇到错误。

如您所见,我正在对代码进行一些修改并编写了两次。我怎样才能让它优雅高效?我相信必须有非常简单的方法来做到这一点。

也欢迎任何关于更改源数据的数据格式或使用合并/连接方法的替代方法的建议/想法。

我希望输出“备注”值存储在列表中。请找到我所做的截图

在此处输入图像描述

标签: pythonregexpython-3.xpandasdataframe

解决方案


您应该尽可能避免在 pandas 中使用显式循环,因为它们不会被矢量化(在 pandas 和 numpy 措辞中进行了优化)。在这里你可以合并你的数据框:

  1. 场景一:

    # extract values where df2.level_0 == df1.VARIABLE
    tmp = pd.merge(pd.DataFrame(df2.level_0), df1.loc[:,['home', 'VARIABLE', 'Remarks']],
         left_on = ['level_0'], right_on=['VARIABLE'])
    # drop lines where home would not contain a digit
    tmp.drop(tmp.loc[~tmp.home.astype(np.str_).str.contains(r'\d')].index,
         inplace=True)
    # extract the Remarks column into a list
    lst = tmp.Remarks.tolist()
    

    使用您的示例数据,我得到[2000000001, 4265453, 4135376]

  2. 场景二:

    tmp = pd.merge(pd.DataFrame(df2['0']), df1.loc[:,['PERSONAL INFORMATION',
                              'VARIABLE', 'Remarks']],
         left_on = ['0'], right_on=['PERSONAL INFORMATION'])
    tmp.drop(tmp.loc[~tmp['VARIABLE'] == 'dummy'].index, inplace=True)
    lst.extend(tmp.Remarks.tolist())
    

    使用您的示例数据,我没有得到额外的值,因为从第一步开始,tmp就是一个空数据框。


推荐阅读