Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python数据框中选择最接近的日期每月的第一天_Python_Pandas_Nearest Neighbor - Fatal编程技术网

在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