Select 行(按可变条件)(即每行中的所需值取决于其他行中的值)
Select rows by variable condition (ie. desired value in each row depends on values in other rows)
我有以下 DataFrame:
model_year cylinders mpg
0 70 4 25.285714
1 70 6 20.500000
2 70 8 14.111111
3 71 4 27.461538
4 71 6 18.000000
5 71 8 13.428571
6 72 3 19.000000
7 72 4 23.428571
8 72 8 13.615385
9 73 3 18.000000
10 73 4 22.727273
11 73 6 19.000000
12 73 8 13.200000
13 74 4 27.800000
14 74 6 17.857143
15 74 8 14.200000
16 75 4 25.250000
17 75 6 17.583333
18 75 8 15.666667
19 76 4 26.766667
20 76 6 20.000000
21 76 8 14.666667
22 77 3 21.500000
23 77 4 29.107143
24 77 6 19.500000
25 77 8 16.000000
26 78 4 29.576471
27 78 5 20.300000
28 78 6 19.066667
29 78 8 19.050000
30 79 4 31.525000
31 79 5 25.400000
32 79 6 22.950000
33 79 8 18.630000
34 80 3 23.700000
35 80 4 34.612000
36 80 5 36.400000
37 80 6 25.900000
38 81 4 32.814286
39 81 6 23.428571
40 81 8 26.600000
41 82 4 32.071429
42 82 6 28.333333
我想要 select 行满足以下条件:
对于每个 model_year select 行,该行具有当年的最小柱面值。
因此,例如,对于模型年份 = 70、71、72 和 73,我想得到:
model_year cylinders mpg
0 70 4 25.285714
3 71 4 27.461538
6 72 3 19.000000
9 73 3 18.000000
我最先进的尝试包括:
- 我将
model_year
和 cylinders
列转换为 DataFrame 的 MultiIndex
- 使用(除其他外)
groupby
方法我获得了我想要 select. 的行的 MultiIndex 对象
但是,我找不到使用 MultiIndex 对象 select 行的方法。
作为参考,我获得的 MultiIndex 是:
MultiIndex([(70, 4),
(71, 4),
(72, 3),
(73, 3),
(74, 4),
(75, 4),
(76, 4),
(77, 3),
(78, 4),
(79, 4),
(80, 3),
(81, 4),
(82, 4)],
names=['model_year', 'cylinders'])
您可以使用 groupby
+ idxmin
创建遮罩并用它过滤 df
:
out = df.loc[df.groupby('model_year')['cylinders'].idxmin()]
输出:
model_year cylinders mpg
0 70 4 25.285714
3 71 4 27.461538
6 72 3 19.000000
9 73 3 18.000000
13 74 4 27.800000
16 75 4 25.250000
19 76 4 26.766667
22 77 3 21.500000
26 78 4 29.576471
30 79 4 31.525000
34 80 3 23.700000
38 81 4 32.814286
41 82 4 32.071429
我认为更简单的解决方案实际上是使用 groupby
+ transform
:
selected = df[df['cylinders'] == df.groupby('model_year')['cylinders'].transform('min')]
输出:
>>> selected
model_year cylinders mpg
0 70 4 25.285714
3 71 4 27.461538
6 72 3 19.000000
9 73 3 18.000000
13 74 4 27.800000
16 75 4 25.250000
19 76 4 26.766667
22 77 3 21.500000
26 78 4 29.576471
30 79 4 31.525000
34 80 3 23.700000
38 81 4 32.814286
41 82 4 32.071429
(请注意,如果一个组有多个最小值(例如,对于 model_year 70,有两个 4 缸行),它们将包含在输出中。)
你可以试试
out = df.sort_values('cylinders',ascending=False).drop_duplicates('model_year')
我有以下 DataFrame:
model_year cylinders mpg
0 70 4 25.285714
1 70 6 20.500000
2 70 8 14.111111
3 71 4 27.461538
4 71 6 18.000000
5 71 8 13.428571
6 72 3 19.000000
7 72 4 23.428571
8 72 8 13.615385
9 73 3 18.000000
10 73 4 22.727273
11 73 6 19.000000
12 73 8 13.200000
13 74 4 27.800000
14 74 6 17.857143
15 74 8 14.200000
16 75 4 25.250000
17 75 6 17.583333
18 75 8 15.666667
19 76 4 26.766667
20 76 6 20.000000
21 76 8 14.666667
22 77 3 21.500000
23 77 4 29.107143
24 77 6 19.500000
25 77 8 16.000000
26 78 4 29.576471
27 78 5 20.300000
28 78 6 19.066667
29 78 8 19.050000
30 79 4 31.525000
31 79 5 25.400000
32 79 6 22.950000
33 79 8 18.630000
34 80 3 23.700000
35 80 4 34.612000
36 80 5 36.400000
37 80 6 25.900000
38 81 4 32.814286
39 81 6 23.428571
40 81 8 26.600000
41 82 4 32.071429
42 82 6 28.333333
我想要 select 行满足以下条件: 对于每个 model_year select 行,该行具有当年的最小柱面值。
因此,例如,对于模型年份 = 70、71、72 和 73,我想得到:
model_year cylinders mpg
0 70 4 25.285714
3 71 4 27.461538
6 72 3 19.000000
9 73 3 18.000000
我最先进的尝试包括:
- 我将
model_year
和cylinders
列转换为 DataFrame 的 MultiIndex - 使用(除其他外)
groupby
方法我获得了我想要 select. 的行的 MultiIndex 对象
但是,我找不到使用 MultiIndex 对象 select 行的方法。
作为参考,我获得的 MultiIndex 是:
MultiIndex([(70, 4),
(71, 4),
(72, 3),
(73, 3),
(74, 4),
(75, 4),
(76, 4),
(77, 3),
(78, 4),
(79, 4),
(80, 3),
(81, 4),
(82, 4)],
names=['model_year', 'cylinders'])
您可以使用 groupby
+ idxmin
创建遮罩并用它过滤 df
:
out = df.loc[df.groupby('model_year')['cylinders'].idxmin()]
输出:
model_year cylinders mpg
0 70 4 25.285714
3 71 4 27.461538
6 72 3 19.000000
9 73 3 18.000000
13 74 4 27.800000
16 75 4 25.250000
19 76 4 26.766667
22 77 3 21.500000
26 78 4 29.576471
30 79 4 31.525000
34 80 3 23.700000
38 81 4 32.814286
41 82 4 32.071429
我认为更简单的解决方案实际上是使用 groupby
+ transform
:
selected = df[df['cylinders'] == df.groupby('model_year')['cylinders'].transform('min')]
输出:
>>> selected
model_year cylinders mpg
0 70 4 25.285714
3 71 4 27.461538
6 72 3 19.000000
9 73 3 18.000000
13 74 4 27.800000
16 75 4 25.250000
19 76 4 26.766667
22 77 3 21.500000
26 78 4 29.576471
30 79 4 31.525000
34 80 3 23.700000
38 81 4 32.814286
41 82 4 32.071429
(请注意,如果一个组有多个最小值(例如,对于 model_year 70,有两个 4 缸行),它们将包含在输出中。)
你可以试试
out = df.sort_values('cylinders',ascending=False).drop_duplicates('model_year')