pandas DataFrame窗口功能 [英] Pandas DataFrame Window Function
问题描述
我正在尝试像使用SQL窗口函数一样操作我的数据框.考虑以下样本集:
I'm trying to manipulate my data frame similar to how you would using SQL window functions. Consider the following sample set:
import pandas as pd
df = pd.DataFrame({'fruit' : ['apple', 'apple', 'apple', 'orange', 'orange', 'orange', 'grape', 'grape', 'grape'],
'test' : [1, 2, 1, 1, 2, 1, 1, 2, 1],
'analysis' : ['full', 'full', 'partial', 'full', 'full', 'partial', 'full', 'full', 'partial'],
'first_pass' : [12.1, 7.1, 14.3, 19.1, 17.1, 23.4, 23.1, 17.2, 19.1],
'second_pass' : [20.1, 12.0, 13.1, 20.1, 18.5, 22.7, 14.1, 17.1, 19.4],
'units' : ['g', 'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g'],
'order' : [2, 1, 3, 2, 1, 3, 3, 2, 1]})
+--------+------+----------+------------+-------------+-------+-------+
| fruit | test | analysis | first_pass | second_pass | order | units |
+--------+------+----------+------------+-------------+-------+-------+
| apple | 1 | full | 12.1 | 20.1 | 2 | g |
| apple | 2 | full | 7.1 | 12.0 | 1 | g |
| apple | 1 | partial | 14.3 | 13.1 | 3 | g |
| orange | 1 | full | 19.1 | 20.1 | 2 | g |
| orange | 2 | full | 17.1 | 18.5 | 1 | g |
| orange | 1 | partial | 23.4 | 22.7 | 3 | g |
| grape | 1 | full | 23.1 | 14.1 | 3 | g |
| grape | 2 | full | 17.2 | 17.1 | 2 | g |
| grape | 1 | partial | 19.1 | 19.4 | 1 | g |
+--------+------+----------+------------+-------------+-------+-------+
我想添加几列:
- 一个布尔列,指示该测试和分析的second_pass值在所有水果类型中是否最高.
- 另一列,列出了每种测试和分析组合的哪些水果的second_pass值最高.
使用此逻辑,我想获得下表:
Using this logic, I'd like to get the following table:
+--------+------+----------+------------+-------------+-------+-------+---------+---------------------+
| fruit | test | analysis | first_pass | second_pass | order | units | highest | highest_fruits |
+--------+------+----------+------------+-------------+-------+-------+---------+---------------------+
| apple | 1 | full | 12.1 | 20.1 | 2 | g | true | ["apple", "orange"] |
| apple | 2 | full | 7.1 | 12.0 | 1 | g | false | ["orange"] |
| apple | 1 | partial | 14.3 | 13.1 | 3 | g | false | ["orange"] |
| orange | 1 | full | 19.1 | 20.1 | 2 | g | true | ["apple", "orange"] |
| orange | 2 | full | 17.1 | 18.5 | 1 | g | true | ["orange"] |
| orange | 1 | partial | 23.4 | 22.7 | 3 | g | true | ["orange"] |
| grape | 1 | full | 23.1 | 22.1 | 3 | g | false | ["orange"] |
| grape | 2 | full | 17.2 | 17.1 | 2 | g | false | ["orange"] |
| grape | 1 | partial | 19.1 | 19.4 | 1 | g | false | ["orange"] |
+--------+------+----------+------------+-------------+-------+-------+---------+---------------------+
我是熊猫的新手,所以我确定我缺少一些简单的东西.
I'm new to pandas, so I'm sure I'm missing something very simple.
推荐答案
您可以返回boolean
值,其中second_pass
等于group
max
,因为idxmax
仅返回
You could return boolean
values where second_pass
equals the group
max
, as idxmax
only returns the first occurrence of the max
:
df['highest'] = df.groupby(['test', 'analysis'])['second_pass'].transform(lambda x: x == np.amax(x)).astype(bool)
,然后使用np.where
捕获具有group
max
的所有fruit
值,并将结果merge
捕获到您的DataFrame
中,如下所示:
and then use np.where
to capture all fruit
values that have a group
max
, and merge
the result into your DataFrame
like so:
highest_fruits = df.groupby(['test', 'analysis']).apply(lambda x: [f for f in np.where(x.second_pass == np.amax(x.second_pass), x.fruit.tolist(), '').tolist() if f!='']).reset_index()
df =df.merge(highest_fruits, on=['test', 'analysis'], how='left').rename(columns={0: 'highest_fruit'})
最后,请您跟进:
first_pass = df.groupby(['test', 'analysis']).apply(lambda x: {fruit: x.loc[x.fruit==fruit, 'first_pass'] for fruit in x.highest_fruit.iloc[0]}).reset_index()
df =df.merge(first_pass, on=['test', 'analysis'], how='left').rename(columns={0: 'first_pass_highest_fruit'})
获得:
analysis first_pass fruit order second_pass test units highest \
0 full 12.1 apple 2 20.1 1 g True
1 full 7.1 apple 1 12.0 2 g False
2 partial 14.3 apple 3 13.1 1 g False
3 full 19.1 orange 2 20.1 1 g True
4 full 17.1 orange 1 18.5 2 g True
5 partial 23.4 orange 3 22.7 1 g True
6 full 23.1 grape 3 14.1 1 g False
7 full 17.2 grape 2 17.1 2 g False
8 partial 19.1 grape 1 19.4 1 g False
highest_fruit first_pass_highest_fruit
0 [apple, orange] {'orange': [19.1], 'apple': [12.1]}
1 [orange] {'orange': [17.1]}
2 [orange] {'orange': [23.4]}
3 [apple, orange] {'orange': [19.1], 'apple': [12.1]}
4 [orange] {'orange': [17.1]}
5 [orange] {'orange': [23.4]}
6 [apple, orange] {'orange': [19.1], 'apple': [12.1]}
7 [orange] {'orange': [17.1]}
8 [orange] {'orange': [23.4]}
这篇关于 pandas DataFrame窗口功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!