<p>将<a href="http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.transform.html" rel="nofollow noreferrer">^{<cd1>}</a>与<a href="http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.first.html" rel="nofollow noreferrer">^{<cd2>}</a>和一起使用
<a href="http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.last.html" rel="nofollow noreferrer">^{<cd3>}</a>,对于新列,<a href="http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.add_prefix.html" rel="nofollow noreferrer">^{<cd4>}</a>和<a href="http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.join.html" rel="nofollow noreferrer">^{<cd5>}</a>是一种可能的解决方案:</p>
<pre><code>df = pd.DataFrame(ex)
#columns for processing defined after groupby
g = df.groupby(['grp', 'grp2'])['val1', 'val2']
out = df.join((g.transform('last') - g.transform('first')).add_prefix('new_'))
</code></pre>
<p>如评论中提到的@Wen Ben是不带<code>join</code>的可能替代品(谢谢):</p>
<pre><code>df[['new_val1', 'new_val2']] = g.transform('last') - g.transform('first')
</code></pre>
<hr/>
<pre><code>print (out)
grp grp2 val1 val2 new_val1 new_val2
0 828893 NaN -50.0 0.0 NaN NaN
1 828893 NaN -50.0 0.0 NaN NaN
2 828893 NaN -50.0 0.0 NaN NaN
3 828893 NaN -50.0 0.0 NaN NaN
4 828893 1 7.6 30.1 93.2 -8.5
5 828893 1 54.6 21.5 93.2 -8.5
6 828893 1 38.6 20.7 93.2 -8.5
7 828893 1 50.6 4.2 93.2 -8.5
8 828893 1 91.0 5.0 93.2 -8.5
9 828893 1 100.8 21.6 93.2 -8.5
10 828893 NaN 19.2 85.1 NaN NaN
11 828893 NaN -50.0 0.0 NaN NaN
12 828893 2 -50.0 0.0 140.2 51.2
13 828893 2 69.6 36.4 140.2 51.2
14 828893 2 42.0 56.6 140.2 51.2
15 828893 2 90.2 51.2 140.2 51.2
16 828893 NaN -50.0 0.0 NaN NaN
17 828893 NaN -50.0 0.0 NaN NaN
18 828893 NaN 47.6 58.5 NaN NaN
19 828893 3 98.8 42.2 0.0 0.0
20 828893 NaN 27.6 76.1 NaN NaN
21 828893 4 11.8 68.7 -11.8 26.6
22 828893 4 NaN NaN -11.8 26.6
23 828893 4 13.0 90.3 -11.8 26.6
24 828893 4 0.0 95.3 -11.8 26.6
</code></pre>