【问题标题】:Expand dataframe for each date | Pandas为每个日期展开数据框 |熊猫
【发布时间】:2021-02-22 04:12:25
【问题描述】:

我有一个用户连接数据框,其中 UID 代表用户,日期代表用户建立连接的日期(由#fans 表示)。

UID     Date        #fans
9305    1/25/2015   5
9305    2/26/2015   7
9305    3/27/2015   8
9305    4/1/2015    9
1305    6/6/2015    14
1305    6/26/2015   16
1305    6/27/2015   17

数据框的日期范围是 01-01-2014 到 12-01-2020。

我需要扩展数据,以便每个用户的日期应该包含日期范围内的每个日期,并且每个日期应该有 #fans 作为用户在该日期之前的总连接数。 例如所需的输出是

UID     Date        #fans
9305    1/1/2014    0
9305    1/2/2014    0
9305    1/3/2014    0
...
9305    1/25/2015   5
9305    1/26/2015   5
9305    1/27/2015   5
...
9305    2/26/2015   7
9305    3/27/2015   8
9305    3/28/2015   8
9305    3/29/2015   8
...
9305    4/1/2015    9
...
9305    12/1/2020   9

*for all the UIDs

我不确定我应该在这里采取什么方法。任何帮助表示赞赏。

【问题讨论】:

  • 从 01-01-2014 到 12-01-2020 之间有 2,526 天。所以你想要 2526 x # of UUIDs 作为行。对于每一行,您希望 UUID 在 #fans 列中有一个值。中间日期将具有来自#fans 的较早值。我的理解正确吗?
  • 创建一个与您的用例匹配的小型数据集要好得多。这似乎是thisthis 的欺骗

标签: pandas dataframe


【解决方案1】:

下面的代码应该会给你想要的结果。

  1. 第 1 步:创建一个 pd.Series 日期范围在 01-01-2014 和 2020 年 12 月 1 日。

    datelist = pd.date_range(start='01-01-2014', end='12-01-2020', freq='1d')

  2. 第 2 步:获取日期范围的长度。在我们的例子中,它是 2527。

    nd = len(datelist)

  3. 第3步:获取原始UID的唯一值的长度 数据框。在示例中,我们有 2

    nu = len(df['UID'].unique())

  4. 第 4 步:创建一个包含两列的 DataFrame - UID 和 Date 全范围 (2527 x 2)

    df_final = pd.DataFrame({'UID':df['UID'].unique().tolist()*nd, 'Date':np.repeat(datelist,nu)})

  5. 第 5 步:现在将原始数据框合并到 df_final,这样您就可以 获取分配给 #fans 的特定值。

    df_final = df_final.merge(df, how='left')

  6. 第 6 步:按 UID 分组并向前填充行。如果他们是 NA,将值设置为 0

    df_final[['Date','#fans']] = df_final.groupby('UID')[['Date','#fans']].ffill().fillna(0)

  7. 第 7 步:最后,我们将 #fans 的 dtype 更改为 int 否则 值将与 xx.0 浮动

    df_final['#fans'] = df_final['#fans'].astype('int64')

将所有这些放在一起,代码如下:

import pandas as pd
import numpy as np
from datetime import datetime

c = ['UID','Date','#fans']
d = [[9305,    '1/25/2015',   5],
[9305,    '2/26/2015',  7],
[9305,    '3/27/2015',   8],
[9305,    '4/1/2015',    9],
[1305,    '6/6/2015',   14],
[1305,    '6/26/2015',   16],
[1305,    '6/27/2015',   17]]
df = pd.DataFrame(d,columns=c)
df.Date = pd.to_datetime(df.Date)
print (df)

datelist = pd.date_range(start='01-01-2014', end='12-01-2020', freq='1d')
nd = len(datelist)
nu = len(df['UID'].unique())

df_final = pd.DataFrame({'UID':df['UID'].unique().tolist()*nd,
                         'Date':np.repeat(datelist,nu)})

df_final = df_final.merge(df, how='left')

df_final[['Date','#fans']] = df_final.groupby('UID')[['Date','#fans']].ffill().fillna(0)

df_final['#fans'] = df_final['#fans'].astype('int64')
print (df_final)

这个输出将是:

       UID       Date  #fans
1     1305 2014-01-01      0
3     1305 2014-01-02      0
5     1305 2014-01-03      0
7     1305 2014-01-04      0
9     1305 2014-01-05      0
...    ...        ...    ...
5044  9305 2020-11-27      9
5046  9305 2020-11-28      9
5048  9305 2020-11-29      9
5050  9305 2020-11-30      9
5052  9305 2020-12-01      9

上面的代码还考虑了从一个 UID 到另一个 UID 的转换。

代码将确保以下内容:

       UID       Date  #fans
2526  1305 2020-12-01     17
       UID       Date  #fans
2527  9305 2014-01-01      0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 2020-01-14
    • 2021-10-21
    • 1970-01-01
    • 2017-05-16
    • 1970-01-01
    • 2021-07-11
    相关资源
    最近更新 更多