我有以下数据框:
id subid a
1 1 1 2
2 1 1 10
3 1 1 20
4 1 2 30
5 1 2 35
6 1 2 36
7 1 2 40
8 2 2 20
9 2 2 29
10 2 2 30
我想在列" a"上应用say例如pandas diff()函数,但只要" id"都应该重新应用该函数。或者" subid"正在更改,并希望将值存储在新列中。
以下是我期望的df。
id subid a difference
1 1 1 2 NaN
2 1 1 10 8
3 1 1 20 10
4 1 2 30 NaN
5 1 2 35 5
6 1 2 36 1
7 1 2 40 4
8 2 2 20 NaN
9 2 2 29 9
10 2 2 30 1
在Row-4和Row-8可以观察到" id"或者" subid"正在改变,因此存在NaN值,并且在连续的行中计算diff。
已使用
df["difference"] = df["a"].diff()
显然适用于整个列,而不是预期的方式。我尝试过使用groupby,但它以某种方式提供额外的行。
提前感谢您的任何建议。
答案 0 :(得分:2)
试试这个:
In [97]: df['difference'] = df.groupby(['id','subid'])['a'].diff()
In [98]: df
Out[98]:
id subid a difference
1 1 1 2 NaN
2 1 1 10 8.0
3 1 1 20 10.0
4 1 2 30 NaN
5 1 2 35 5.0
6 1 2 36 1.0
7 1 2 40 4.0
8 2 1 20 NaN
9 2 1 29 9.0
10 2 1 30 1.0
答案 1 :(得分:2)
这是一个棘手的问题。根据您的确切措辞,您希望在'id'
或'subid'
更改的每个位置重置。这意味着即使他们来回变换。
此外,diff
计算如果在groupby
上下文中完成,则不会产生影响,因此我会预先计算它并在事情发生变化时进行屏蔽。
i = df.id.values
s = df.subid.values
i_chg = np.append(False, i[:-1] != i[1:])
s_chg = np.append(False, s[:-1] != s[1:])
df.assign(difference=df.a.diff().mask(i_chg | s_chg))
id subid a difference
1 1 1 2 NaN
2 1 1 10 8.0
3 1 1 20 10.0
4 1 2 30 NaN
5 1 2 35 5.0
6 1 2 36 1.0
7 1 2 40 4.0
8 2 1 20 NaN
9 2 1 29 9.0
10 2 1 30 1.0
答案 2 :(得分:2)
<强>设置强>
df = pd.DataFrame({'a': {1: 2, 2: 10, 3: 20, 4: 30, 5: 35, 6: 36, 7: 40, 8: 20, 9: 29, 10: 30},
'id': {1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 2, 9: 2, 10: 2},
'subid': {1: 1, 2: 1, 3: 1, 4: 2, 5: 2, 6: 2, 7: 2, 8: 1, 9: 1, 10: 1}})
<强>解决方案强>
#Check for each row if the id-subid pair has changed with previous row and then calculate diff accordingly
df['difference'] = df.apply(lambda x: x.a - df.ix[x.name-1].a
if (x.name>1 and x[['id','subid']].equals(df.ix[x.name-1][['id','subid']]))
else np.nan, axis=1)
df
Out[368]:
a id subid difference
1 2 1 1 NaN
2 10 1 1 8.0
3 20 1 1 10.0
4 30 1 2 NaN
5 35 1 2 5.0
6 36 1 2 1.0
7 40 1 2 4.0
8 20 2 1 NaN
9 29 2 1 9.0
10 30 2 1 1.0