熊猫四舍五入到最近的一个月的第一天



我有一个日期列表,大约在 30 日至 2 日,我想将所有这些四舍五入到该月的第一天(30 日/31 日的舍入和第 1 日/2 日向下,依此类推(。

如何在熊猫数据帧中执行此操作?

首先,确保您的"日期"列数据类型是日期类型。例如

df['date'] = pd.to_datetime(df['date'])

将"日期"列的 dtype 更改为 datetime64[ns]。

接下来考虑问题的范围。你想改变2月28日/29日吗?我假设您只想更改指定的日期。这可以通过两部分轻松完成。首先找到较早的日期,然后将其向前移动,然后找到较晚的日期并将其移回。

若要将早期日期向前移动,请创建一个掩码来选择有问题的行。

mask1 = (df['birth_date'].dt.day >= 30)

然后用 pandas .apply(( 方法和专门定制的函数更改日期。这应该被矢量化,因此速度相当快。

from dateutil.relativedelta import relativedelta
df.loc[mask1, 'birth_date'] = df.loc[mask1, 'birth_date'].apply(lambda date_in: (date_in + relativedelta(months=+1)).replace(day=1))

同样,对于需要提前移动的日期(即当 day = 2 时(,我们有如下。

mask2 = (df['birth_date'].dt.day == 2)
df.loc[mask2, 'birth_date'] = df.loc[mask2, 'birth_date'].apply(lambda date_in: (date_in).replace(day=1))

例如:

输入:

raw_data = {'name': ['Willard Morris', 'Al Jennings', 'Omar Mullins', 'Spencer McDaniel'],
'age': [20, 19, 22, 21],
'favorite_color': ['blue', 'red', 'yellow', "green"],
'grade': [88, 92, 95, 70],
'birth_date': ['01-02-1996', '08-05-1997', '04-30-1996', '12-16-1995']}
df = pd.DataFrame(raw_data, index = ['Willard Morris', 'Al Jennings', 'Omar Mullins', 'Spencer McDaniel'])
df['birth_date'] = pd.to_datetime(df['birth_date'])
df

输出:

name                age    favorite_color    grade    birth_date('%y%m%d')
Willard Morris      20     blue              88       1996-01-02
Al Jennings         19     red               92       1997-08-05
Omar Mullins        22     yellow            95       1996-04-30
Spencer McDaniel    21     green             70       1995-12-16

输入:

mask1 = (df['birth_date'].dt.day >= 30)
mask2 = (df['birth_date'].dt.day == 2)
df.loc[mask1, 'birth_date'] = df.loc[mask1, 'birth_date'].apply(lambda date_in: (date_in + relativedelta(months=+1)).replace(day=1))
df.loc[mask2, 'birth_date'] = df.loc[mask2, 'birth_date'].apply(lambda date_in: date_in.replace(day=1))
df

输出:

name                age    favorite_color    grade    birth_date('%y%m%d')
Willard Morris      20     blue              88       1996-01-01
Al Jennings         19     red               92       1997-08-05
Omar Mullins        22     yellow            95       1996-05-01
Spencer McDaniel    21     green             70       1995-12-16

如果您要做的是将最接近月初的日子向上和向下舍入,则可以分两步完成:

rng = pd.date_range('1/25/2018 11:59:00', periods=14, freq='D')
s = pd.Series(rng)
# round down 
s.where(((s.dt.day == 1) | (s.dt.day > 2)), 
lambda x: x + pd.offsets.MonthBegin(-1), inplace=True)
# round up 
s.where(s.dt.day < 30, lambda x: x + pd.offsets.MonthBegin(0), inplace=True)  

结果:

In [317]: s
Out[317]: 
0    2018-01-25 11:59:00
1    2018-01-26 11:59:00
2    2018-01-27 11:59:00
3    2018-01-28 11:59:00
4    2018-01-29 11:59:00
5    2018-02-01 11:59:00
6    2018-02-01 11:59:00
7    2018-02-01 11:59:00
8    2018-02-01 11:59:00
9    2018-02-03 11:59:00
10   2018-02-04 11:59:00
11   2018-02-05 11:59:00
12   2018-02-06 11:59:00
13   2018-02-07 11:59:00
dtype: datetime64[ns]

相关内容

最新更新