我有熊猫的df,有每日数据。我想返回每个月的最后一个值。我以为简单的解决方案将是.resample("M").apply(lambda ser: ser.iloc[-1,])
,但是似乎resample
实际上是在计算月结束日期,而不是返回该月出现的实际日期。这是预期的行为吗? MWE:
import pandas as pd
import numpy as np
df = pd.Series(np.arange(100), index=pd.date_range(start="2000-01-02", periods=100)).to_frame()
df.sort_index().resample("M").apply(lambda ser: ser.iloc[-1,])
# 0
#2000-01-31 29
#2000-02-29 58
#2000-03-31 89
#2000-04-30 99
df
中出现的最后一个日期是2000-04-10
答案 0 :(得分:2)
您可能需要查看groupby
+ tail
df.groupby(df.index.month).tail(1)
Out[18]:
0
2000-01-31 29
2000-02-29 58
2000-03-31 89
2000-04-10 99
答案 1 :(得分:2)
通过将resample
与offset M
一起使用,您可以 下采样 ,直到日历月底(请参见偏移量的链接文档),然后传递函数。因此,您的索引将始终是该月的最后一天,这确实是预期的行为。您正在应用的函数(lambda ser: ser.iloc[-1,]
)只是说:对于这一天结束的日历日期,原始数据中找到的最后一个值是什么。
例如,您还可以使用偏移量MS
而不是M
重新采样到月份开始,结果将是相同的,除了索引将是 first 日历月的一天,而不是最后一天:
# Resample to month end, as you had originally:
>>> df.sort_index().resample("M").apply(lambda ser: ser.iloc[-1,])
0
2000-01-31 29
2000-02-29 58
2000-03-31 89
2000-04-30 99
# Resample to month start: same data, except index is month start instead of month end
>>> df.sort_index().resample("MS").apply(lambda ser: ser.iloc[-1,])
0
2000-01-01 29
2000-02-01 58
2000-03-01 89
2000-04-01 99
正如Wen指出的那样,如果您只想显示数据中的实际最后日期,最好使用groupby。 重采样在要将数据上采样或下采样到不同时间频率时很有用 ,而不是从原始时间频率中选择真实数据
>