gpt4 book ai didi

python - 根据属性将两个人匹配在一起

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:05:24 24 4
gpt4 key购买 nike

我有一个包含不同人的数据框。每行包含表征个人的属性。基本上我需要像过滤器或匹配算法这样的东西来加权特定属性。数据框如下所示:

df= pd.DataFrame({
'sex' : [m,f,m,f,m,f],
'food' : [0,0,1,3,4,3],
'age': [young, young, young, old, young, young]
'kitchen': [0,1,2,0,1,2],
})

数据框 df 如下所示:

    sex food  age     kitchen
0 m 0 young 0
1 f 0 young 1
2 m 1 young 2
3 f 3 old 0
4 m 4 young 1
5 f 3 young 2

我正在寻找一种算法,该算法将数据帧中的所有人分组成对。我的计划是根据以下属性找到成对的两个人:

  1. 一个人必须有厨房(kitchen=1)
    至少一个人拥有厨房是很重要的。

    kitchen=0 --> 这个人没有厨房

    kitchen=1 --> person has a kitchen

    kitchen=2 --> 人有厨房但只有在紧急情况下(没有其他选择时)

  2. 相同的食物偏好

    food=0 --> 肉食者

    food=1 --> 无所谓

    食物=2 --> 素食主义者

    food=3 --> 素食

    肉食者 (food=0) 可以与不关心食物偏好的人 (food=1) 匹配,但不能与素食主义者或素食者匹配。素食主义者 (food=2) 最适合素食主义者 (food=3),如有必要,可以搭配 food=1。等等……

  3. 年龄相仿

    有九个年龄段:10-18; 18-22; 22-26; 26-29、29-34; 34-40; 40-45; 45-55 和 55-75。同一年龄段的人非常匹配。年轻的年龄组与年长的年龄组并不匹配。相似的年龄组匹配得更好一些。没有明确定义的条件。 “老”和“年轻”的意思是相对的。

性别无关紧要。有许多可能的配对组合。因为我的实际数据框很长(3000 行),所以我需要找到一个自动化的解决方案。在数据框或字典或其他东西中为我提供最佳配对的解决方案。

我真的不知道如何解决这个问题。我一直在 Stack Overflow 上寻找类似的问题,但没有找到合适的。主要是太理论上了。我也找不到真正适合我的问题的东西。

我在这里的预期输出是,例如字典(不确定如何)或以每两行可以看作一对的方式排序的数据框。

背景:目标是结对进行一些空闲时间事件。因此我认为,相同或相似年龄段的人有相同的兴趣,因此我想在我的代码中考虑这个事实。

最佳答案

我通过将 'name' 作为识别此人的 key 来完成添加。

方法

方法是我对值进行评分,这些值进一步用于根据给定条件过滤最终对。

厨房评分

我们使用的厨房分数:

  • 没有厨房的人:0
  • 拥有厨房的人:1
  • 人有厨房但只在紧急情况下:0.5

厨房的if条件逻辑

我们检查[记录 1 的厨房得分] + [记录 2 的厨房得分] 是否大于零。由于会出现以下情况:

  1. 两位成员都没有厨房(总和将为 0)[排除条件 > 0]
  2. 两位成员都有厨房(总和为 2)
  3. 一个成员有厨房,另一个没有厨房(总和为 1)
  4. 两者都有应急厨房(总和为 1)
  5. 一个有应急厨房,另一个有厨房(总和为 1.5)
  6. 一名成员有应急厨房,另一名成员没有厨房(总和为 0.5)

食物评分

我们使用的食物分数:

  • 食物 = 0 --> 肉食者:-1
  • food = 1 --> 无所谓:0
  • 食物 = 2 --> 素食主义者:1
  • 食物 = 3 --> 素食者:1

食物的if条件逻辑

我们检查 *[记录 1 的食物得分] * [记录 2 的食物得分]* 是否大于或等于。由于会出现以下情况:

  1. 两个成员都是肉食者:-1 x -1 = 1 [已包含]
  2. 其中一名成员是肉食者和其他纯素食者或素食者:-1 x 1 = -1 [排除]
  3. 成员之一是肉食者,其他成员无关紧要:-1 x 0 = 0 [已包含]
  4. 其中一位成员是素食主义者或素食主义者,其他无关紧要:1 x 0 = 0 [已包含]
  5. 两位成员都是纯素食者或素食者:1 x 1 = 1 [已包含]

年龄组评分

对于评分年龄组,我们为这些组分配了一些值:

  • 10-18 : 1
  • 18-22 : 2
  • 22-26 : 3
  • 26-29 : 4
  • 29-34 : 5
  • 34-40 : 6
  • 40-45 : 7
  • 45-55 : 8
  • 55-75 : 9

年龄分数计算

为了计算年龄得分,使用了以下公式:age_score = round((1 - (abs(人 1 的年龄组值 - 人 2 的年龄组值)/10)), 2)

在上面的公式中我们做了如下计算:

  1. 首先我们计算了两个人的年龄组值之间的差异的绝对值。
  2. 然后我们将它除以 10 以对其进行归一化。
  3. 此外,我们从 1 中减去该值以反转距离,因此在这一步之后,我们对相似​​或更接近年龄组的人具有更高的值,而对于不同或更远年龄组的人具有更低的值。

案例如下:

  1. 18-22 和 18-22: round(1 - (abs(2 - 2)/10), 2) = 1.0
  2. 45-55 和 45-55 : round(1 - (abs(8 - 8)/10), 2) = 1.0
  3. 18-22 和 45-55: round(1 - (abs(2 - 8)/10), 2) = 0.4
  4. 10-18 和 55-75: round(1 - (abs(1 - 9)/10), 2) = 0.2

最终分数计算

为了计算最终分数,我们使用了:

最终得分 = 食物得分 + 厨房得分 + 年龄得分

然后我们对最终得分数据进行排序以获得最佳配对。

解决方案代码

import pandas as pd
import numpy as np

# Creating the DataFrame, here I have added the attribute 'name' for identifying the record.
df = pd.DataFrame({
'name' : ['jacob', 'mary', 'rick', 'emily', 'sabastein', 'anna',
'christina', 'allen', 'jolly', 'rock', 'smith', 'waterman',
'mimi', 'katie', 'john', 'rose', 'leonardo', 'cinthy', 'jim',
'paul'],
'sex' : ['m', 'f', 'm', 'f', 'm', 'f', 'f', 'm', 'f', 'm', 'm', 'm', 'f',
'f', 'm', 'f', 'm', 'f', 'm', 'm'],
'food' : [0, 0, 1, 3, 2, 3, 1, 0, 0, 3, 3, 2, 1, 2, 1, 0, 1, 0, 3, 1],
'age' : ['10-18', '22-26', '29-34', '40-45', '18-22', '34-40', '55-75',
'45-55', '26-29', '26-29', '18-22', '55-75', '22-26', '45-55',
'10-18', '22-26', '40-45', '45-55', '10-18', '29-34'],
'kitchen' : [0, 1, 2, 0, 1, 2, 2, 1, 0, 0, 1, 0, 1, 1, 1, 0, 2, 0, 2, 1],
})

# Adding a normalized field 'k_scr' for kitchen
df['k_scr'] = np.where((df['kitchen'] == 2), 0.5, df['kitchen'])

# Adding a normalized field 'f_scr' for food
df['f_scr'] = np.where((df['food'] == 1), 0, df['food'])
df['f_scr'] = np.where((df['food'] == 0), -1, df['f_scr'])
df['f_scr'] = np.where((df['food'] == 2), 1, df['f_scr'])
df['f_scr'] = np.where((df['food'] == 3), 1, df['f_scr'])

# Adding a normalized field 'a_scr' for age
df['a_scr'] = np.where((df['age'] == '10-18'), 1, df['age'])
df['a_scr'] = np.where((df['age'] == '18-22'), 2, df['a_scr'])
df['a_scr'] = np.where((df['age'] == '22-26'), 3, df['a_scr'])
df['a_scr'] = np.where((df['age'] == '26-29'), 4, df['a_scr'])
df['a_scr'] = np.where((df['age'] == '29-34'), 5, df['a_scr'])
df['a_scr'] = np.where((df['age'] == '34-40'), 6, df['a_scr'])
df['a_scr'] = np.where((df['age'] == '40-45'), 7, df['a_scr'])
df['a_scr'] = np.where((df['age'] == '45-55'), 8, df['a_scr'])
df['a_scr'] = np.where((df['age'] == '55-75'), 9, df['a_scr'])

# Printing DataFrame after adding normalized score values
print(df)

commonarr = [] # Empty array for our output
dfarr = np.array(df) # Converting DataFrame to Numpy Array
for i in range(len(dfarr) - 1): # Iterating the Array row
for j in range(i + 1, len(dfarr)): # Iterating the Array row + 1
# Check for Food Condition to include relevant records
if dfarr[i][6] * dfarr[j][6] >= 0:
# Check for Kitchen Condition to include relevant records
if dfarr[i][5] + dfarr[j][5] > 0:
row = []
# Appending the names
row.append(dfarr[i][0])
row.append(dfarr[j][0])
# Appending the final score
row.append((dfarr[i][6] * dfarr[j][6]) +
(dfarr[i][5] + dfarr[j][5]) +
(round((1 - (abs(dfarr[i][7] -
dfarr[j][7]) / 10)), 2)))

# Appending the row to the Final Array
commonarr.append(row)

# Converting Array to DataFrame
ndf = pd.DataFrame(commonarr)

# Sorting the DataFrame on Final Score
ndf = ndf.sort_values(by=[2], ascending=False)
print(ndf)

带分数的输入/中间数据帧

         name sex  food    age  kitchen  k_scr  f_scr a_scr
0 jacob m 0 10-18 0 0.0 -1 1
1 mary f 0 22-26 1 1.0 -1 3
2 rick m 1 29-34 2 0.5 0 5
3 emily f 3 40-45 0 0.0 1 7
4 sabastein m 2 18-22 1 1.0 1 2
5 anna f 3 34-40 2 0.5 1 6
6 christina f 1 55-75 2 0.5 0 9
7 allen m 0 45-55 1 1.0 -1 8
8 jolly f 0 26-29 0 0.0 -1 4
9 rock m 3 26-29 0 0.0 1 4
10 smith m 3 18-22 1 1.0 1 2
11 waterman m 2 55-75 0 0.0 1 9
12 mimi f 1 22-26 1 1.0 0 3
13 katie f 2 45-55 1 1.0 1 8
14 john m 1 10-18 1 1.0 0 1
15 rose f 0 22-26 0 0.0 -1 3
16 leonardo m 1 40-45 2 0.5 0 7
17 cinthy f 0 45-55 0 0.0 -1 8
18 jim m 3 10-18 2 0.5 1 1
19 paul m 1 29-34 1 1.0 0 5

输出

             0          1    2
48 sabastein smith 4.0
10 mary allen 3.5
51 sabastein katie 3.4
102 smith jim 3.4
54 sabastein jim 3.4
99 smith katie 3.4
61 anna katie 3.3
45 sabastein anna 3.1
58 anna smith 3.1
14 mary rose 3.0
12 mary mimi 3.0
84 allen cinthy 3.0
98 smith mimi 2.9
105 waterman katie 2.9
11 mary jolly 2.9
50 sabastein mimi 2.9
40 emily katie 2.9
52 sabastein john 2.9
100 smith john 2.9
90 rock smith 2.8
47 sabastein rock 2.8
0 jacob mary 2.8
17 mary paul 2.8
13 mary john 2.8
119 katie jim 2.8
116 mimi paul 2.8
111 mimi john 2.8
103 smith paul 2.7
85 allen paul 2.7
120 katie paul 2.7
.. ... ... ...

这个解决方案还有进一步的优化空间。

关于python - 根据属性将两个人匹配在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53996421/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com