当前位置: 首页 > 知识库问答 >
问题:

筛选数据以仅获取月份的第一天行

洪飞龙
2023-03-14

我有一个每日数据集。我只需要获得数据集中每个月的第一天的数据(数据是从1972年到2013年)。例如,我需要提取0.1555索引20,日期2013-12-02值。我的问题是每个月的第一天是不同的,因此我不能使用诸如relativedelta(months=1)之类的步骤,我该如何从数据集中提取这些值?

有没有类似的命令,我在另一个职位上发现的R?

R-XTS:从缺少行的每日时间序列中获取每个月的第一个日期和值

17 2013-12-05 0.1621
18 2013-12-04 0.1698
19 2013-12-03 0.1516
20 2013-12-02 0.1555
21 2013-11-29 0.1480
22 2013-11-27 0.1487
23 2013-11-26 0.1648

共有3个答案

金阳曜
2023-03-14
import pandas as pd
dates = pd.date_range('2014-02-05', '2014-03-15', freq='D') 
df = pd.DataFrame({'vals': range(len(dates))}, index=dates)
g = df.groupby(lambda x: x.strftime('%Y-%m'), axis=0)
g.apply(lambda x: x.index.min())
#Or depending on whether you want the index or the vals
g.apply(lambda x: x.ix[x.index.min()])
徐佐
2023-03-14

一种方法是为年、月和日添加列:

df['year'] = df.SomeDatetimeColumn.map(lambda x: x.year)
df['month'] = df.SomeDatetimeColumn.map(lambda x: x.month)
df['day'] = df.SomeDatetimeColumn.map(lambda x: x.day)

然后按年份和月份分组,按天订购,只取第一个条目(这将是最短的日条目)。

df.groupby(
    ['year', 'month']
).apply(lambda x: x.sort('day', ascending=True)).head(1)

使用lambda表达式使其不太适合大型数据集。您可能不希望通过保持单独存储的年、月和日值来增加数据的大小。然而,对于这些特殊的日期对齐问题,迟早将这些值分开是非常有帮助的。

另一种方法是通过datetime列的函数直接分组:

dfrm.groupby(
    by=dfrm.dt.map(lambda x: (x.year, x.month))
).apply(lambda x: x.sort('dt', ascending=True).head(1))

通常出现这些问题是因为在Python/熊猫层之前存在一个级别的功能失调的数据库或数据存储模式。

例如,在这种情况下,依赖日历数据库表或日历数据集的存在应该是司空见惯的,日历数据集包含(或易于查询)一个月中相对于给定数据集的最早活动日期(例如,第一个交易日,第一个星期,第一个工作日,第一个假期,或者其他什么)。

如果有一个伴数据库表与此数据一起存在,那么将它与您已经加载的数据集结合起来应该很容易(例如,通过加入您已经拥有的日期列),然后只需对日历数据应用逻辑过滤器列。

一旦你需要使用日期滞后,这就变得尤为重要:例如,将公司1个月前的市值与公司当月的股票回报对齐,以计算1个月期间实现的总回报。

这可以通过使用shift延迟pandas中的列来实现,或者尝试进行复杂的自连接,这可能非常容易出现错误,并造成将特定日期约定永久化到下游使用该代码数据的每个位置的问题。

更好的方法是简单地要求(或者自己做)数据必须在其原始格式(数据库、平面文件等)中具有适当的规范化日期特征,并停止你正在做的事情,首先解决日期问题,然后再回到执行用日期数据做一些分析

柴禄
2023-03-14

我会按月份分组,然后得到每组的第0(n)行。

首先设置为索引(我认为这是必要的):

In [11]: df1 = df.set_index('date')

In [12]: df1
Out[12]:
             n     val
date
2013-12-05  17  0.1621
2013-12-04  18  0.1698
2013-12-03  19  0.1516
2013-12-02  20  0.1555
2013-11-29  21  0.1480
2013-11-27  22  0.1487
2013-11-26  23  0.1648

下一个排序,使第一个元素是该月的第一个日期(注意:对于n,这似乎不是必需的,但我认为这实际上是一个bug!):

In [13]: df1.sort_index(inplace=True)

In [14]: df1.groupby(pd.TimeGrouper('M')).nth(0)
Out[14]:
             n     val
date
2013-11-26  23  0.1648
2013-12-02  20  0.1555

另一个选项是重新采样并获取第一个条目:

In [15]: df1.resample('M', 'first')
Out[15]:
             n     val
date
2013-11-30  23  0.1648
2013-12-31  20  0.1555

考虑到这一点,您可以通过提取月份,然后根据该月份进行分组来实现更简单的操作:

In [21]: pd.DatetimeIndex(df.date).to_period('M')
Out[21]:
<class 'pandas.tseries.period.PeriodIndex'>
[2013-12, ..., 2013-11]
Length: 7, Freq: M

In [22]: df.groupby(pd.DatetimeIndex(df.date).to_period('M')).nth(0)
Out[22]:
    n       date     val
0  17 2013-12-05  0.1621
4  21 2013-11-29  0.1480

这一次df.date的排序是(正确的)相关的,如果你知道它是按降序日期排列的,你可以使用nth(-1)

In [23]: df.groupby(pd.DatetimeIndex(df.date).to_period('M')).nth(-1)
Out[23]:
    n       date     val
3  20 2013-12-02  0.1555
6  23 2013-11-26  0.1648

如果不能保证这一点,则首先按日期列排序:df.sort('date')

 类似资料:
  • 问题内容: 我正在尝试选择当前日期前三个月的每月的第一天。 因此,例如,如果当前日期是:“ 2015-11-08”,我的结果将是:“ 2015-08-01” 我希望这是yyyy-mm-dd格式。 我从一开始就尝试过,但是没有运气: 我已经尝试了很多事情,但似乎无法破解,任何建议或帮助都将不胜感激。先感谢您 问题答案: 逻辑很简单: 减去当月的日期减去日期后的1天 减去三个月 在SQL Server

  • 问题内容: 如何在SELECT中查找一年中的第一天? 我找到了这个月份-但是我没有足够的掌握年份的信息:(我一直在寻找一个单独的查询来查找月份开始和现在之间的数据) 问题答案: 我认为您需要: 老实说,您可以执行以下操作:

  • 每次在“调用解析时间”列中有一个新的月份,我都希望用那个月份和年份创建一个新的csv文件。对于包含那个月份和年份的所有行,都要过滤到那个新的csv中。 这样地: 所有数据。csv 新文件于2015年5月发布。从所有数据创建csv。仅限2015年5月20日的csv数据 到目前为止,我有这个,但我必须为每年和每月手动创建一些东西: 编辑---------------------------------

  • 在给定年、月和周的情况下,是否有可能获得一周中第一个日期的DAYOFMONTH? 请注意,一周的第一个日期也可能是前一个月,甚至是前一年。 我知道这是可以通过编程实现的,至少使用java。时间、时间场等。。但我想在sql查询级别上这样做,因为当涉及周时,过程中会涉及两个额外的参数,即被视为一周的第一天的DayOfWeek和一个月内一周的最小天数。如果sql和api上的配置不完全相同,则可能会导致不

  • 我有一个LocalDate,需要得到一个月的第一天和最后一天。我该怎么做? 我需要获取LocalDate格式的和。 使用Three-Ten LocalDate类。