将熊猫df1的每一行与df2中的每一行进行比较,并从最接近的匹配列返回字符串值

时间:2020-04-12 08:10:02

标签: python pandas dataframe

我有两个数据帧。

df1的体重和身高(英寸)包括4名男性和4名女性。

#df1
John, 236, 76
Jack, 204, 74
Jim, 156, 71
Jared, 182, 72
Suzy, 119, 60
Sally, 149, 66
Sharon, 169, 65
Sammy, 182, 75

df2的体重和身高(英寸)包括4名男性和4名女性。

#df2
Aaron, 285, 77
Abe, 236, 75
Alex, 178, 72
Adam, 195, 71
Mary, 148, 66
Maylee, 155, 66
Marilyn, 199, 65
Madison, 160, 73

我要做的是将df1的男人与df2的男人进行比较,以根据身高和体重看他们最喜欢谁。只需从体重减去体重,再从身高减去身高,然后为df2中的每个人返回一个绝对值。更具体地说,返回最相似的人的名字。

因此,在这种情况下,John最接近的匹配是Abe,因此在新列中 df1['doppelganger'] = "Abe"

我是一个初学者,所以即使指向正确的方向也会很有帮助。我一直在研究堆栈溢出大约五个小时,试图弄清楚如何处理这种情况。

1 个答案:

答案 0 :(得分:1)

首先必须区分menwomen,这里使用重复4次mf的新列。然后将DataFrame.merge与所有组合的新列一起用于外部联接,并为差异创建新列,最后一列是其中的sum。然后按DataFrame.sort_values按3列排序,因此每组的第一行按AgDataFrame.drop_duplicates进行过滤:

df = (df1.assign(g = ['m']*4 + ['f']*4)
          .merge(df2.assign(g = ['m']*4 + ['f']*4), on='g', how='outer', suffixes=('','_'))
          .assign(dif1 = lambda x: x['B'].sub(x['B_']).abs(),
                  dif2 = lambda x: x['C'].sub(x['C_']).abs(),
                  sumdiff = lambda x: x['dif1'] + x['dif2'])
          .sort_values(['A', 'g','sumdiff'])
          .drop_duplicates(['A','g'])
          .sort_index()
          .rename(columns={'A_':'doppelganger'})
          )
print (df)
         A    B   C  g doppelganger   B_  C_  dif1  dif2  sumdiff
1     John  236  76  m          Abe  236  75     0     1        1
7     Jack  204  74  m         Adam  195  71     9     3       12
10     Jim  156  71  m         Alex  178  72    22     1       23
14   Jared  182  72  m         Alex  178  72     4     0        4
16    Suzy  119  60  f         Mary  148  66    29     6       35
20   Sally  149  66  f         Mary  148  66     1     0        1
25  Sharon  169  65  f       Maylee  155  66    14     1       15
31   Sammy  182  75  f      Madison  160  73    22     2       24

输入数据框:

print (df1)    
        A    B   C
0    John  236  76
1    Jack  204  74
2     Jim  156  71
3   Jared  182  72
4    Suzy  119  60
5   Sally  149  66
6  Sharon  169  65
7   Sammy  182  75

print (df2)
         A    B   C
0    Aaron  285  77
1      Abe  236  75
2     Alex  178  72
3     Adam  195  71
4     Mary  148  66
5   Maylee  155  66
6  Marilyn  199  65
7  Madison  160  73