这个月的第一个日期的日期如何?

Joh*_*ass 9 python numpy date pandas

我有一个带有索引列=的pandas DataFrame date.

输入:

            value
date    
1986-01-31  22.93
1986-02-28  15.46
Run Code Online (Sandbox Code Playgroud)

我想把日期定在那个月的第一天

输出:

            value
date    
1986-01-01  22.93
1986-02-01  15.46
Run Code Online (Sandbox Code Playgroud)

我尝试了什么:

df.index.floor('M')
ValueError: <MonthEnd> is a non-fixed frequency
Run Code Online (Sandbox Code Playgroud)

这可能是因为df是由 df = df.resample("M").sum()(此代码的输出是问题开头的输入)生成的

我也试过了df = df.resample("M", convention='start').sum().但是,它不起作用.

我知道在R中,很容易打电话floor(date, 'M').

Deo*_*ung 26

有一个关于地板问题的熊猫问题

建议的方法是

import pandas as pd
pd.to_datetime(df.date).dt.to_period('M').dt.to_timestamp()
Run Code Online (Sandbox Code Playgroud)


Vai*_*ali 10

您可以使用timeseries偏移MonthBegin

from pandas.tseries.offsets import MonthBegin
df['date'] = pd.to_datetime(df['date']) - MonthBegin(1)
Run Code Online (Sandbox Code Playgroud)

编辑:上述解决方案不处理已经落到本月初的日期.这是另一种解决方案.

这是一个包含其他测试用例的数据框:

            value
date    
1986-01-31  22.93
1986-02-28  15.46
2018-01-01  20.00
2018-02-02  25.00
Run Code Online (Sandbox Code Playgroud)

用timedelta方法,

df.index = pd.to_datetime(df.index)
df.index = df.index - pd.to_timedelta(df.index.day - 1, unit='d')


            value
date    
1986-01-01  22.93
1986-02-01  15.46
2018-01-01  20.00
2018-02-01  25.00
Run Code Online (Sandbox Code Playgroud)

  • 这是所有答案中唯一的pandonic方法(作为奖励,这是矢量化) (4认同)
  • 此方法存在一个错误:它将任何日期转换为下个月的月初,但月初除外,该日期保持不变。即1-1-2018-&gt; 1-1-2018,但是2-1-2018-&gt; 1-2-2018 ... (2认同)

Mik*_*kov 9

您还可以使用字符串日期时间格式:

df['month'] = df['date'].dt.strftime('%Y-%m-01')


Grr*_*Grr 7

这将解决问题,无需导入。Numpy 有一个 dtype datetime64,默认情况下,pandas[ns]通过检查 dtype设置为。您可以将其更改为月份,该月份将通过访问 numpy 数组并更改类型从该月的第一天开始。

df.date = pd.to_datetime(df.date.values.astype('datetime64[M]'))
Run Code Online (Sandbox Code Playgroud)

如果大熊猫能用自己的astype()方法实现这一点会很好,但不幸的是你不能。

以上适用于作为日期时间值或字符串的数据,如果您已经将数据作为datetime[ns]类型,则可以省略pd.to_datetime()并且只需执行以下操作:

df.date = df.date.values.astype('datetime64[M]')
Run Code Online (Sandbox Code Playgroud)


ald*_*nor 6

这是另一种“狂热”的方法:

df.date - pd.Timedelta('1 day') * (df.date.dt.day - 1)
Run Code Online (Sandbox Code Playgroud)