【问题标题】:Dataframe Wrangling with Dates and Periods in Pandas数据框与 Pandas 中的日期和期间争吵
【发布时间】:2013-09-15 08:38:27
【问题描述】:

我通常会在 SQL 和 excel 中做很多事情,而我正在尝试用 Pandas 做这些事情。这里有几个不同的争论问题,合并为一个问题,因为它们都有相同的目标。

我在 python 中有一个包含三列的数据框 df:

   |  EventID  |  PictureID  |  Date
0  |  1        |  A          |  2010-01-01
1  |  2        |  A          |  2010-02-01
2  |  3        |  A          |  2010-02-15
3  |  4        |  B          |  2010-01-01
4  |  5        |  C          |  2010-02-01
5  |  6        |  C          |  2010-02-15

EventID 是唯一的。 PictureID 不是唯一的,尽管 PictureID + Date 是不同的。

我。首先,我想添加一个新列:

df['period'] = the month and year that the event falls into beginning 2010-01.

二。其次,我想将数据“融合”到一些新的数据帧中,该数据帧计算给定时间段内给定 PictureID 的事件数。我将使用只有两个句点的示例。

   |  PictureID  |  Period  | Count
0  |  A          |  2010-01 | 1
1  |  A          |  2010-02 | 2
2  |  B          |  2010-01 | 1
3  |  C          |  2010-02 | 2

这样我就可以将这个新数据帧堆叠(?)到为所有唯一 PictureID 提供周期计数的东西中:

   |  PictureID  |  2010-01 | 2010-02
0  |  A          |  1       | 2
1  |  B          |  1       | 0
2  |  C          |  0       | 2

我的感觉是,pandas 的构建很容易做到这一点,对吗?

[编辑:删除了令人困惑的第三部分。]

【问题讨论】:

    标签: python numpy pandas


    【解决方案1】:

    前两部分你可以做:

    >>> df['Period'] = df['Date'].map(lambda d: d.strftime('%Y-%m'))
    >>> df
       EventID PictureID                Date   Period
    0        1         A 2010-01-01 00:00:00  2010-01
    1        2         A 2010-02-01 00:00:00  2010-02
    2        3         A 2010-02-15 00:00:00  2010-02
    3        4         B 2010-01-01 00:00:00  2010-01
    4        5         C 2010-02-01 00:00:00  2010-02
    5        6         C 2010-02-15 00:00:00  2010-02
    >>> grouped = df[['Period', 'PictureID']].groupby('Period')
    >>> grouped['PictureID'].value_counts().unstack(0).fillna(0)
    Period  2010-01  2010-02
    A             1        2
    B             1        0
    C             0        2
    

    对于第三部分,要么我没有很好地理解这个问题,要么你没有在示例中发布正确的数字。因为第三行中A 的计数应该是 2?而对于第 6 行的 C 应该是 1。如果期限是六个月...

    无论哪种方式,您都应该这样做:

    >>> ts = df.set_index('Date')
    >>> ts.resample('6M', ...)
    

    更新:这是一种非常丑陋的方法,我想我看到了一种更好的方法,但我找不到 SO 问题。但是,这也将完成工作......

    def for_half_year(row, data):
        date = row['Date']
        pid = row['PictureID']
        # Do this 6 month checking better
        if '__start' not in data or (date - data['__start']).days > 6*30:
            # Reset values
            for key in data:
                data[key] = 0
            data['__start'] = date
        data[pid] = data.get(pid, -1) + 1
        return data[pid]
    
    df['PastSix'] = df.apply(for_half_year, args=({},), axis=1)
    

    【讨论】:

    • 非常感谢。第三行 A 的计数应该是 2!但我认为这更难做到,而且只计算周期可能更容易。 IE。因为第 2 行和第 3 行都是 2010-02 年的图片 A,所以将前 6 个期间的总和相加只会算 1。但是如果有一种方法可以捕获第 3 行应该是 2,那将非常有帮助。会尝试你放下的。
    • 对这个问题的第三部分理解比较好,涉及的比较多,会移到自己的地方。
    • @user1893148 我为问题的第三部分添加了一个简单的解决方案。我认为有更好的方法来做到这一点,但我找不到我看到的 SO 问题。
    • 关于弄乱问题结构的教训。太棒了。非常感谢。把它放在新问题上可能是有意义的。我不知道正确的 stackoverflow 礼仪。
    • 经过检查,上面的函数似乎不仅仅计算前六个月——它还计算了更远的过去事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2021-09-26
    • 2018-03-29
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多