【问题标题】:How to iterate over a dataframe with publish date column to make a daily mapping table如何迭代具有发布日期列的数据框以制作每日映射表
【发布时间】:2019-11-04 22:17:14
【问题描述】:

我正在使用 Python 3.7 来完成这项任务。 我有一个存储博客 ID、博客名称和发布日期的数据框。我需要将其转换为一个新的数据框,它将每天和 URL 映射到 ID 是什么。我需要这个来运行前一天的日期(截至撰写本文时为 20191103)。假设包括一篇文章不能在一天内重新发布两次,并且任何博客都不需要在发布日期之前有任何日期。

例子:

data = [[1234, 'Blog1', 20191030], [1235,'Blog1', 20191101], [1237,'Blog1', 20191102], [1236,'Blog2', 20191101]]
df = pd.DataFrame(data, columns = ['ID', 'Blog Name', 'Publish Date'])
df.head()

起始数据框:

     ID  Blog Name  Publish Date
0   1234    Blog1   20191030
1   1235    Blog1   20191101
2   1237    Blog1   20191102
3   1236    Blog2   20191101

目标:最终数据框:

   Blog Name  Date    ID
0   Blog1   20191030 1234
1   Blog1   20191031 1234
2   Blog1   20191101 1235
3   Blog1   20191102 1237
4   Blog1   20191103 1237
5   Blog1   20191101 1236
6   Blog2   20191102 1236
7   Blog2   20191103 1236

我主要不确定如何最好地迭代数据框,我是否在原始数据框中创建另一个列并带有“下一个发布日期”,然后在新数据框中为“发布日期”之间的每个日期创建一行和“下一个发布日期”?

解决方案:(由 Code Different 提供)

# Your Publish Date column is string, Need to convert it to Timestamp
df['Publish Date'] = pd.to_datetime(df['Publish Date'], format='%Y%m%d')

def summarize(g):
    # A date range that covers from the first Publish Date to the current day
    d = pd.date_range(g['Publish Date'].min(), pd.Timestamp.now(), name='Publish Date').to_frame(index=False)

    # The merge. This also has the effect of filling any gap in the
    # Publish Date
    return pd.merge_asof(d, g, on='Publish Date')


df.sort_values(['Blog Name', 'Publish Date']) \
    .groupby('Blog Name').apply(summarize) \
    .reset_index(drop=True)

【问题讨论】:

  • 是否需要重复每条记录直到第二天有记录?
  • @phalanx 是的,我需要重复每条记录直到前一天(相对于当天)

标签: python-3.x pandas date dataframe


【解决方案1】:

merge_asof 的完美工作:

# Your Publish Date column is string, Need to convert it to Timestamp
df['Publish Date'] = pd.to_datetime(df['Publish Date'], format='%Y%m%d')

def summarize(g):
    # A date range that covers from the first Publish Date to the current day
    d = pd.date_range(g['Publish Date'].min(), pd.Timestamp.now(), name='Publish Date').to_frame(index=False)

    # The merge. This also has the effect of filling any gap in the
    # Publish Date
    return pd.merge_asof(d, g, on='Publish Date')


df.sort_values(['Blog Name', 'Publish Date']) \
    .groupby('Blog Name').apply(summarize) \
    .reset_index(drop=True)

结果(假设今天 = 2019-11-04):

  Publish Date    ID Blog Name
0   2019-10-30  1234     Blog1
1   2019-10-31  1234     Blog1
2   2019-11-01  1235     Blog1
3   2019-11-02  1237     Blog1
4   2019-11-03  1237     Blog1
5   2019-11-04  1237     Blog1
6   2019-11-01  1236     Blog2
7   2019-11-02  1236     Blog2
8   2019-11-03  1236     Blog2
9   2019-11-04  1236     Blog2

【讨论】:

  • 太完美了!比我计划的任何恶作剧都要好:)
猜你喜欢
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
  • 2014-04-10
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多