Pandas table 查找
Pandas table lookup
我有一个 pandas 查找 table 看起来像这样
Grade Lower_Boundary Upper_Boundary
1 -110 -96
2 -96 -91
3 -91 -85
4 -85 -81
5 -81 -77
6 -77 -72
7 -72 -68
8 -68 -63
9 -63 -58
10 -58 -54
11 -54 -50
12 -50 -46
13 -46 -42
14 -42 -38
15 -38 -34
16 -34 -28
17 -28 -18
18 -18 -11
19 -11 -11
20 -11 -9
我有另一个 pandas 数据框,看起来包含分数。我想通过查找 table 将 'Grade' 分配给分数列。因此,根据分数落在下边界和上边界的哪个区间,应该从查找中的那一行分配分数 table。有没有办法不用输入一堆 if then else 语句就可以做到这一点?我只想到 excel 的索引匹配。
Score Grade
-75 6
-75 6
-60 9
-66 8
-66 8
-98 1
-60 9
-82 4
-70 7
-60 9
-60 9
-60 9
-56 10
-70 7
-70 7
-70 7
-66 8
-56 10
-66 8
-66 8
一个在线解决方案(我称你的查找table lookup
):
df['Score'].apply(lambda score: lookup['Grade'][(lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)].values[0])
解释:
对于给定的分数,以下是查找分数的方法:
score = -75
match = (lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)
grade = lookup['Grade'][match]
这是一个长度为1的return序列。你可以得到它的值,例如:
grade.values[0]
您需要做的就是apply
上面的分数栏。如果你想要单行,请使用 lambda
函数:
df['Score'].apply(lambda score: lookup['Grade'][(lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)].values[0])
否则下面的内容会更具可读性:
def lookup_grade(score):
match = (lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)
grade = lookup['Grade'][match]
return grade.values[0]
df['Score'].apply(lookup_grade)
这种方法还可以更轻松地处理未找到匹配项的情况。
一个选项是 conditional_join from pyjanitor,也包括重叠间隔:
# pip install pyjanitor
import pandas as pd
import janitor
(df2
.conditional_join(
df1,
('Score', 'Lower_Boundary', '>='),
('Score', 'Upper_Boundary', '<='),
how = 'left')
.loc[:, ['Score', 'Grade']]
)
Score Grade
0 -75 6
1 -75 6
2 -60 9
3 -66 8
4 -66 8
5 -98 1
6 -60 9
7 -82 4
8 -70 7
9 -60 9
10 -60 9
11 -60 9
12 -56 10
13 -70 7
14 -70 7
15 -70 7
16 -66 8
17 -56 10
18 -66 8
19 -66 8
您也可以使用 pd.IntervalIndex
实现此目的,而且速度应该更快,尤其是当您的数据没有重叠间隔时。
我有一个 pandas 查找 table 看起来像这样
Grade Lower_Boundary Upper_Boundary
1 -110 -96
2 -96 -91
3 -91 -85
4 -85 -81
5 -81 -77
6 -77 -72
7 -72 -68
8 -68 -63
9 -63 -58
10 -58 -54
11 -54 -50
12 -50 -46
13 -46 -42
14 -42 -38
15 -38 -34
16 -34 -28
17 -28 -18
18 -18 -11
19 -11 -11
20 -11 -9
我有另一个 pandas 数据框,看起来包含分数。我想通过查找 table 将 'Grade' 分配给分数列。因此,根据分数落在下边界和上边界的哪个区间,应该从查找中的那一行分配分数 table。有没有办法不用输入一堆 if then else 语句就可以做到这一点?我只想到 excel 的索引匹配。
Score Grade
-75 6
-75 6
-60 9
-66 8
-66 8
-98 1
-60 9
-82 4
-70 7
-60 9
-60 9
-60 9
-56 10
-70 7
-70 7
-70 7
-66 8
-56 10
-66 8
-66 8
一个在线解决方案(我称你的查找table lookup
):
df['Score'].apply(lambda score: lookup['Grade'][(lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)].values[0])
解释:
对于给定的分数,以下是查找分数的方法:
score = -75
match = (lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)
grade = lookup['Grade'][match]
这是一个长度为1的return序列。你可以得到它的值,例如:
grade.values[0]
您需要做的就是apply
上面的分数栏。如果你想要单行,请使用 lambda
函数:
df['Score'].apply(lambda score: lookup['Grade'][(lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)].values[0])
否则下面的内容会更具可读性:
def lookup_grade(score):
match = (lookup['Lower_Boundary'] <= score) & (lookup['Upper_Boundary'] > score)
grade = lookup['Grade'][match]
return grade.values[0]
df['Score'].apply(lookup_grade)
这种方法还可以更轻松地处理未找到匹配项的情况。
一个选项是 conditional_join from pyjanitor,也包括重叠间隔:
# pip install pyjanitor
import pandas as pd
import janitor
(df2
.conditional_join(
df1,
('Score', 'Lower_Boundary', '>='),
('Score', 'Upper_Boundary', '<='),
how = 'left')
.loc[:, ['Score', 'Grade']]
)
Score Grade
0 -75 6
1 -75 6
2 -60 9
3 -66 8
4 -66 8
5 -98 1
6 -60 9
7 -82 4
8 -70 7
9 -60 9
10 -60 9
11 -60 9
12 -56 10
13 -70 7
14 -70 7
15 -70 7
16 -66 8
17 -56 10
18 -66 8
19 -66 8
您也可以使用 pd.IntervalIndex
实现此目的,而且速度应该更快,尤其是当您的数据没有重叠间隔时。