【问题标题】:Python How do I count the number of month of 30 days after a datePython如何计算日期后30天的月份数
【发布时间】:2017-06-06 11:36:19
【问题描述】:

我有一个包含日期的数据框,我想按如下方式处理数据以进行特征工程

df

date
2016/1/1
2015/2/10
2016/4/5

处理后我想让df看起来像

date      Jan    Feb   Mar   Apr    
2016/1/1  30     0    0      0    //date from 1/1 to 1/30 : the number of dates in jan
2015/2/10  0     19   11     0    //date from 2/10 to 3/11 : the number of dates in feb and no of dates in mar
2016/3/25  0     0    7     21    //date from 3/25 to 4/21 : the number of dates in mar and no of dates in apr
  1. 获取 df["date"] 后 30 天

    df["date"] + timedelta(month=1)

  2. 统计属于特定 30 天的月份的频率

有什么方法可以快速做到这一点?

谢谢。

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 你好 @MrGrj ,只能想到 31 - df["date"].date 来获取休息日,然后使用 30- 休息日来获取下个月的天数。但不要知道如何将它们自动放入列中

标签: python pandas time


【解决方案1】:

一步一步来。首先,您将原始日期偏移+ pd.to_timedelta('30d')。然后创建一个仅由df.date.dt.month 指示月份的列。然后为每个日期创建一个包含月末日期的列 - 一些想法在这里:Want the last day of each month for a data frame in pandas。最后,填写一个以 12 个月为列的矩阵,设置月份和月份+1 列中的值。

通过一次丰富一列的 DataFrame,您可以轻松地从输入转移到所需的输出。不可能有一种神奇的方法可以在一次调用中完成所有操作。

在此处阅读有关 Pandas 中日期/时间函数的所有信息:https://pandas.pydata.org/pandas-docs/stable/timeseries.html - 有很多!

【讨论】:

  • 感谢您的评论。
【解决方案2】:

您可以将自定义函数与date_rangegroupbysize 一起使用:

date = df[['date']]
names = ['Jan', 'Feb','Mar','Apr','May']

def f(x):
    print (x['date'])
    a = pd.date_range(x['date'], periods=30)
    a = pd.Series(a).groupby(a.month).size()
    return (a)


df = df.apply(f, axis=1).fillna(0).astype(int)
df = df.rename(columns = {k:v for k,v in enumerate(names)})
df = date.join(df)
print (df)
        date  Feb  Mar  Apr  May
0 2016-01-01   30    0    0    0
1 2015-02-10    0   19   11    0
2 2016-03-25    0    0    7   23

value_counts类似的解决方案:

date = df[['date']]
names = ['Jan', 'Feb','Mar','Apr','May']

df = df.apply(lambda x: pd.date_range(x['date'], periods=30).month.value_counts(), axis=1)
       .fillna(0)
       .astype(int)
df = df.rename(columns = {k:v for k,v in enumerate(names)})
df = date.join(df)
print (df)

另一种解决方案:

names = ['Jan', 'Feb','Mar','Apr','May']
date = df[['date']]

df["date1"] = df["date"] + pd.Timedelta(days=29)
df = df.reset_index().melt(id_vars='index', value_name='date').set_index('date')
df = df.groupby('index').resample('D').asfreq()
df = df.groupby([df.index.get_level_values(0), df.index.get_level_values(1).month])
      .size()
      .unstack(fill_value=0)
df = df.rename(columns = {k+1:v for k,v in enumerate(names)})
df = date.join(df)
print (df)
        date  Jan  Feb  Mar  Apr
0 2016-01-01   30    0    0    0
1 2015-02-10    0   19   11    0
2 2016-03-25    0    0    7   23

【讨论】:

  • 谢谢,这是一个很好的使用日期_range的方法,而且使用起来非常快。你很聪明,我很佩服你哈哈
  • @LeighLove - 我不确定我是否聪明,因为这个解决方案花费了我 2 个小时的时间 ;) 但非常有趣的问题,祝你好运!
猜你喜欢
  • 2016-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多