python - 从熊猫数据框中同一字段的所有其他行中减去一行字段中的值
问题描述
我有一个数据框,如下所示:
data = {'sid':[1,1,1,2,2,2],
'field1':['start', None, None, 'start', None, None],
'field2':['a', 'b', 'z', 'd', 'z','s'],
'val':[20, 22, 23, 40, 45, 47]}
df = pd.DataFrame(data)
print(df)
sid field1 val
0 1 start 20
1 1 None 22
2 1 None 23
3 2 start 40
4 2 None 45
5 2 None 47
我想创建一个新字段newval ,它存储该行的val与具有相同sid和field1 = 'start'的行中的val之间的差异。
sid field1 val newval
0 1 start 20 NaN
1 1 None 22 2.0
2 1 None 23 3.0
3 2 start 40 NaN
4 2 None 45 5.0
5 2 None 47 7.0
我已经尝试使用 groupby() 进行 diff() 但这给了我一个运行差异。
df['newval'] = df.groupby('sid')['val'].diff()
sid field1 val newval
0 1 start 20 NaN
1 1 None 22 2.0
2 1 None 23 1.0
3 2 start 40 NaN
4 2 None 45 5.0
5 2 None 47 2.0
如何从特定行中获得差异?
解决方案
您可以将 groupby 与帮助列一起使用sid
,然后获取组的第一个值,然后从val
字段中减去。
df['new_val'] = (df['val']-
df.groupby(['sid',df['field1'].eq("start").cumsum()])['val'].transform("first"))
print(df)
sid field1 field2 val new_val
0 1 start a 20 0
1 1 None b 22 2
2 1 None z 23 3
3 2 start d 40 0
4 2 None z 45 5
5 2 None s 47 7
辅助列如下,有助于分组:
print(df['field1'].eq("start").cumsum())
0 1
1 1
2 1
3 2
4 2
5 2
Name: field1, dtype: int32
推荐阅读
- rust - 不能在 mpsc::channel 上使用 Stream::take_while: bool: Future 不满足
- zsh - “1<”完成了什么?
- javascript - 如何使用 Javascript 一次过滤和搜索多个 div?
- http-headers - 我的 API 上没有安全标头是否被认为是不好的做法?
- python - 在类中使用时关闭 aiohttp ClientSession
- c# - System.IO.DirectoryNotFoundException 怎么解决
- google-cloud-platform - 如何启用/禁用 OAuth 以及请求将如何显示在 Google Cloud Console 中?
- python - 加速 Pandas DataFrame Groupby 应用
- implementation - 在 C++ 中使用 set 实现 Dijkstra 算法
- angular - Angular + OIDC 隐式流静默更新