假设我有以下 Pandas 数据框,
import pandas as pd
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
df = pd.DataFrame([[201901, 'Value1'], [201902, 'Value2'], [201707, 'Value3], columns=['Col1', 'Col2'])
╔════════╦═════════╗
║ Col1 ║ Col2 ║
╠════════╬═════════╣
║ 201901 ║ Value 1 ║
║ 201902 ║ Value 2 ║
║ 201707 ║ Value 3 ║
╚════════╩═════════╝
我希望第一列是这样的(我希望每个月的最后一天):
╔════════════╦═════════╗
║ Col1 ║ Col2 ║
╠════════════╬═════════╣
║ 2019-01-31 ║ Value 1 ║
║ 2019-02-28 ║ Value 2 ║
║ 2017-07-31 ║ Value 3 ║
╚════════════╩═════════╝
所以,为了实现我已经尝试了以下几点:
next_month = {'01':'02', '02':'03',
'03':'04', '04':'05',
'05':'06', '06':'07',
'07':'08', '08':'09',
'09':'10', '10':'11',
'11':'12', '12':'01'}
df = df['Col1'].apply(lambda x: str(int(str(x)[:4])+1) + next_month[str(x)[-2:]
if str(x)[-2:] else str(x)[:4] + next_month[str(x)[-2:]])
df['Col1'] = pd.to_datetime(df['Col1'], format='%Y%m') - timedelta(days=1)
在代码的最后一部分中,我将替换下个月的行月,并检查是否是 12 月,每年添加一个。
有没有办法有效地实现这一目标?我也试过这个,但它花了很多时间,甚至比以前的代码显示的还要多。
df['Col1'] = df['Col1'].apply(lambda x: (x + relativedelta(months=1)) - relativedelta(days=1))
最佳答案
在 numpy 中使用相同的想法来提高性能:
s = pd.to_datetime(df['Col1'], format='%Y%m')
df['Col11'] = (s.to_numpy().astype('datetime64[M]') +
np.array([1], dtype='timedelta64[M]') -
np.array([1], dtype='timedelta64[D]'))
另一个想法是创建字典和
Series.map
:d = dict(zip(pd.date_range('1900', '2100', freq='MS')[:-1],
pd.date_range('1900', '2100', freq='M')))
df['Col12'] = pd.to_datetime(df['Col1'], format='%Y%m').map(d)
print (df)
Col1 Col2 Col11 Col12
0 201901 Value1 2019-01-31 2019-01-31
1 201902 Value2 2019-02-28 2019-02-28
2 201707 Value3 2017-07-31 2017-07-31
关于python - Python 中的天花板日期(类似于 R 的天花板日期),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60302020/