python - 在熊猫多索引数据框中返回满足逻辑索引条件的每个组的最后一行
问题描述
希望返回一个数据框,其中包含每个组的最后一行(具有最近日期索引的行),其中多索引的第二级由逻辑索引条件过滤。
这是一个玩具示例,可以更好地解释:
import numpy as np
import pandas as pd
from datetime import datetime
dates = pd.date_range(start='1/1/2018', end='1/4/2018').to_pydatetime().tolist() * 2
ids = ['z7321', 'z7321', 'z7321', 'z7321', 'b2134', 'b2134', 'b2134', 'b2134']
arrays = [ids, dates]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['key', 'date'])
df = pd.DataFrame(data=np.random.randn(len(index)), index=index, columns=['change'])
print(df)
change
key date
z7321 2018-01-01 -0.701605
2018-01-02 -0.934580
2018-01-03 0.186554
2018-01-04 0.417024
b2134 2018-01-01 0.682699
2018-01-02 -0.913633
2018-01-03 0.330347
2018-01-04 -0.706429
条件是返回最后一行df[df.index.get_level_values(1) <= datetime(2018, 1, 2)]
所需的输出如下所示:
change
key date
z7321 2018-01-02 -0.934580
b2134 2018-01-02 -0.913633
其他注意事项:
- 直接选择使用的行
df[df.index.get_level_values(1) == datetime(2018, 1, 2)]
不是一个选项,因为第二个索引级别(日期级别)可能不包含指定值的精确日期匹配datetime(2018, 1, 2)
- 日期索引可能在键组/索引中包含不同的值。即“z7321”在二级索引中的日期可能与“b2134”不同
解决方案
当我编写我的玩具示例时,我最终找到了一种获得所需输出的方法。希望这个解决方案对其他人有帮助,或者可以改进。
以下提供了所需的输出:
df1 = df[df.index.get_level_values(1) <= datetime(2018, 1, 2)].groupby(level='key', as_index=False).nth(-1)
print(df1)
change
key date
z7321 2018-01-02 -0.934580
b2134 2018-01-02 -0.913633
这也适用于第二个索引级别在第一级组中不一致的情况:
import numpy as np
import pandas as pd
from datetime import datetime
dates = pd.date_range(start='1/1/2018', end='1/4/2018').to_pydatetime().tolist()
dates += pd.date_range(start='12/29/2017', end='1/1/2018').to_pydatetime().tolist()
ids = ['z7321', 'z7321', 'z7321', 'z7321', 'b2134', 'b2134', 'b2134', 'b2134']
arrays = [ids, dates]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['key', 'date'])
df = pd.DataFrame(data=np.random.randn(len(index)), index=index, columns=['change'])
print(df)
change
key date
z7321 2018-01-01 -1.420757
2018-01-02 -0.297835
2018-01-03 0.693520
2018-01-04 0.909420
b2134 2017-12-29 -1.577685
2017-12-30 0.632395
2017-12-31 1.158273
2018-01-01 -0.242314
df1 = df[df.index.get_level_values(1) <= datetime(2018, 1, 2)].groupby(level='key', as_index=False).nth(-1)
print(df1)
change
key date
z7321 2018-01-02 -0.297835
b2134 2018-01-01 -0.242314
推荐阅读
- react-native - 凭据:“省略”选项在 MaxToyberman/react-native-ssl-pinning 中不起作用
- postgresql - 分析查询 postgres
- php - 获取 Wordpress 页面加载的每个函数的执行时间。(用于分析,寻找性能瓶颈)
- build - NextJs 构建失败
- spring-boot - Spring boot Okhttp 调用成功但 RestTemplate 给出 Connection Timed Out
- javascript - 如何从模板创建多个具有给定名称的电子表格
- amazon-web-services - How to insert AWS Cloudtrail logs to AWS Timestream database table?
- python - Plot Math's Fourier Basis Functions w/o Prebuilt Fourier Py Functions
- java - @WithuserDetails 可以在控制器测试期间注入 @AuthenticationPrinciple 吗?
- linux - 套接字缓冲区是否占用进程内存地址?