在python数据框中选择最接近的日期每月的第一天
我有这种数据帧在python数据框中选择最接近的日期每月的第一天,python,pandas,nearest-neighbor,Python,Pandas,Nearest Neighbor,我有这种数据帧 这些数据表示消费指数的值,通常每月编码一次(在下个月底或月初),但有时更高。如果计数器不在并需要更换,此值可以重置为“0”。此外,有几个月没有可用的数据 我希望每个月只选择一个条目,但该条目必须最接近该月的第一天,并且低于该月的第15天(因为如果该天较高,则可能是该月底的度量)。另一个条件是,如果两个值之间的差值为负值(计数器已被替换),则即使该日期不是月的第一天附近的最近日期,也需要保留该值 例如,输出数据需要是 目的是仅计算每月的消耗量 解决方案是解析数据帧(作为数组)并
这些数据表示消费指数的值,通常每月编码一次(在下个月底或月初),但有时更高。如果计数器不在并需要更换,此值可以重置为“0”。此外,有几个月没有可用的数据 我希望每个月只选择一个条目,但该条目必须最接近该月的第一天,并且低于该月的第15天(因为如果该天较高,则可能是该月底的度量)。另一个条件是,如果两个值之间的差值为负值(计数器已被替换),则即使该日期不是月的第一天附近的最近日期,也需要保留该值 例如,输出数据需要是
目的是仅计算每月的消耗量 解决方案是解析数据帧(作为数组)并执行一些if条件语句。然而,我想知道是否有“简单”的替代方案来实现这一点
谢谢您可以使用
MonthEnd
规范化月份数据,然后删除该列的重复项,并保留最后一个
值
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中。定义数据帧,将索引转换为日期时间,定义辅助列, 使用它们运行
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)
也许我不清楚。如果这些截止日期可用:25/5东部时间3/6,则必须保留3/6,因为它更接近项目的第一天month@Ksartor请包含输入数据——您可以执行
df.iloc[0:6]。将结果复制并粘贴到您的问题中。您写了“我希望每月只选择一个条目”,但在所需的输出数据中,10月份有两个条目(05-10-19
和30-10-19
)。请澄清,也许我不清楚。如果这些截止日期可用:25/5 et 3/6,则必须保留3/6,因为它更接近当月的第一天。在这种情况下,5月10日是唯一接近1月10日的日期,30月10日是最近的1月11日。除此情况外,它似乎有效:如果两个值之间的差值为负数(计数器已被替换),则即使该日期不是最接近月份第一天的日期,也需要保留该值。您能举个例子吗?为什么不先重置_索引呢?有了这个数据帧,我还需要在计数器更改时保留4/2/2020的条目(理论上,时间可以添加到数据帧中)df=pd.dataframe([[1277],[1301],[1345],[1541],[12],[175]],columns=[[Value”],index=[dt.strtime(“30-10-19”,“d-%m-%y”),dt.strtime(“04-11-19”,“d-%m-%y”),dt.strtime(“30-11-19”,“d-%m-%y”),dt.strtime(“03-02-20”,“d-%m-%y”),dt.strtime(“04-02-20”,“d-%m-%y”),dt.strtime(“25-02-20”,“d-%m-%y”))
Value
2019-10-05 1254
2019-10-30 1277
2019-11-04 1301
2019-11-30 1345
2020-02-03 1541