数据如下:
return
2010-01-04 0.016676
2010-01-05 0.003839
...
2010-01-05 0.003839
2010-01-29 0.001248
2010-02-01 0.000134
...
我想要的是提取数据中出现的所有值 。
2010-01-29 0.00134
2010-02-28 ......
如果我直接使用pandas.resample,即df.resample(' M).last()。我会用错误的索引选择正确的行。 (它会自动使用该月的最后一天作为索引)
2010-01-31 0.00134
2010-02-28 ......
如何以Pythonic方式获得正确的答案?
答案 0 :(得分:7)
这里假设您的日期数据是索引的一部分。如果没有,我建议先设置它。
我不认为重新取样或石斑鱼功能会这样做。我们将月份编号分组,然后拨打DataFrameGroupBy.tail
。
df.groupby(df.index.month).tail(1)
如果您的数据跨越多年,则需要对年份和月份进行分组。使用从dt.strftime
-
df.groupby(df.index.strftime('%Y-%m')).tail(1)
或者,使用多个石斑鱼 -
df.groupby([df.index.year, df.index.month]).tail(1)
注意 - 如果您的索引不假设为DatetimeIndex
,则需要将df.index
替换为上面的pd.to_datetime(df.index, errors='coerce')
。
答案 1 :(得分:2)
虽然这不能正确回答问题,但如果有人有兴趣,我会留下。
一种方法,只有在您确定自己有所有日子 (!重要)时才能正常工作 .Timedelta并检查是否天== 1.我做了一个小的运行时间测试,它比groupby解决方案 6x 快。
df[(df['dates'] + pd.Timedelta(days=1)).dt.day == 1]
或者索引:
df[(df.index + pd.Timedelta(days=1)).day == 1]
完整示例:
import pandas as pd
df = pd.DataFrame({
'dates': pd.date_range(start='2016-01-01', end='2017-12-31'),
'i': 1
}).set_index('dates')
dfout = df[(df.index + pd.Timedelta(days=1)).day == 1]
print(dfout)
返回:
i
dates
2016-01-31 1
2016-02-29 1
2016-03-31 1
2016-04-30 1
2016-05-31 1
2016-06-30 1
2016-07-31 1
2016-08-31 1
2016-09-30 1
2016-10-31 1
2016-11-30 1
2016-12-31 1
2017-01-31 1
2017-02-28 1
2017-03-31 1
2017-04-30 1
2017-05-31 1
2017-06-30 1
2017-07-31 1
2017-08-31 1
2017-09-30 1
2017-10-31 1
2017-11-30 1
2017-12-31 1