在python数据框中选择最接近的日期每月的第一天

2024-04-25 08:34:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这种数据帧
enter image description here

这些数据表示消费指数的值,通常每月编码一次(在下个月底或月初),但有时更高。如果计数器不在并需要更换,此值可以重置为“0”。此外,有几个月没有可用的数据

我希望每个月只选择一个条目,但该条目必须最接近该月的第一天,并且低于该月的第15天(因为如果该天较高,则可能是该月底的度量)。另一个条件是,如果两个值之间的差值为负值(计数器已被替换),则即使该日期不是月的第一天附近的最近日期,也需要保留该值

例如,输出数据需要是
enter image description here

目的是仅计算每月的消耗量

解决方案是解析数据帧(作为数组)并执行一些if条件语句。然而,我想知道是否有“简单”的替代方案来实现这一点

多谢各位


Tags: 数据目的编码度量计数器条目数组解决方案
2条回答

您可以使用MonthEnd规范化月份数据,然后根据该列删除重复项并保留last

from pandas.tseries.offsets import MonthEnd    
df.New = df.Index + MonthEnd(1)
df.Diff = abs((df.Index - df.New).dt.days)
df = df.sort_values(df.New, df.Diff)
df = df.drop_duplicates(subset='New', keep='first').drop(['New','Diff'], axis=1)

这应该可以解决问题,但我无法进行测试,因此如果这不起作用,请将示例数据复制并传递到StackOverFlow中

定义dataframe,将索引转换为datetime,定义辅助列, 使用它们运行shift方法有条件地删除行,最后删除辅助列:

from pandas.tseries.offsets import MonthEnd, MonthBegin
import pandas as pd
from datetime import datetime as dt
import numpy as np

df = pd.DataFrame([
    [1254],
    [1265],
    [1277],
    [1301],
    [1345],
    [1541]
], columns=["Value"]
, index=[dt.strptime("05-10-19", '%d-%m-%y'),
         dt.strptime("29-10-19", '%d-%m-%y'),
         dt.strptime("30-10-19", '%d-%m-%y'),
         dt.strptime("04-11-19", '%d-%m-%y'),
         dt.strptime("30-11-19", '%d-%m-%y'),
         dt.strptime("03-02-20", '%d-%m-%y')
         ]
)

early_days = df.loc[df.index.day < 15]
early_month_end = early_days.index - MonthEnd(1)
early_day_diff = early_days.index - early_month_end
late_days = df.loc[df.index.day >= 15]
late_month_end = late_days.index + MonthBegin(1)
late_day_diff = late_month_end - late_days.index
df["day_offset"] = (early_day_diff.append(late_day_diff) / np.timedelta64(1, 'D')).astype(int)
df["start_of_month"] = df.index.day < 15
df["month"] = df.index.values.astype('M8[D]').astype(str)
df["month"] = df["month"].str[5:7].str.lstrip('0')
# df["month_diff"] = df["month"].astype(int).diff().fillna(0).astype(int)
df = df[df["month"].shift().ne(df["month"].shift(-1))]
df = df.drop(columns=["day_offset", "start_of_month", "month"])
print(df)

返回:

            Value
2019-10-05   1254
2019-10-30   1277
2019-11-04   1301
2019-11-30   1345
2020-02-03   1541

相关问题 更多 >