从日期 python 获取周数

getting week number from date python

我有如下代码。我的问题:

  1. 为什么将第 1 周分配给 2014-12-29'2014-1-1'?为什么不将第 53 周分配给 2014-12-29
  2. 如何分配不断增加的周数?我 希望 '2014-12-29','2015-1-1' 有第 53 周,'2015-1-15' 有 第 55 周等
x=pd.DataFrame(data=['2014-1-1','2014-12-29','2015-1-1','2015-1-15'],columns=['date'])

x['week_number']=pd.DatetimeIndex(x['date']).week

至于为什么 2014 年 12 月 29 日的周数为 1——请参阅我在评论中链接到的问题。对于你问题的第二部分:

2014 年 1 月 1 日是星期三。我们可以取你日期列的最小日期,得到天数并从差值中减去:

解决方案

# x["date"] = pd.to_datetime(x["date"])  # if not already a datetime column
min_date = x["date"].min() + 1  # + 1 because they're zero-indexed
x["weeks_from_start"] = ((x["date"].diff().dt.days.cumsum() - min_date) // 7 + 1).fillna(1).astype(int)

输出:

        date  weeks_from_start
0 2014-01-01                 1
1 2014-12-29                52
2 2015-01-01                52
3 2015-01-15                54

循序渐进

第一步是将 date 列转换为日期时间类型,如果您还没有的话:

In [3]: x.dtypes
Out[3]:
date    object
dtype: object

In [4]: x["date"] = pd.to_datetime(x["date"])

In [5]: x
Out[5]:
        date
0 2014-01-01
1 2014-12-29
2 2015-01-01
3 2015-01-15

In [6]: x.dtypes
Out[6]:
date    datetime64[ns]
dtype: object

接下来,我们需要找到您的日期列的最小值,并将其设置为开始日期的星期几(加 1,因为日期从 0 开始):

In [7]: x["date"].min().day + 1
Out[7]: 2

接下来用built-in.diff()函数取相邻行的差:

In [8]: x["date"].diff()
Out[8]:
0        NaT
1   362 days
2     3 days
3    14 days
Name: date, dtype: timedelta64[ns]

请注意,对于第一个条目,我们得到 NaT(“不是时间”)——这是因为第一行与上面的行没有可比性。

解释这些值的方式是第 1 行是第 0 行之后的 362 天,第 2 行是第 1 行之后的 3 天,依此类推

如果您计算累计总和并减去开始日期,您将得到自开始日期以来的天数,在本例中为 2014-01-01,就好像星期三是第一周的第 0 天(这是因为当我们计算自该开始日期以来的周数时,我们需要补偿星期三是该周中间的事实):

In [9]: x["date"].diff().dt.days.cumsum() - min_date
Out[9]:
0      NaN
1    360.0
2    363.0
3    377.0
Name: date, dtype: float64

现在,当我们将底数除以 7 时,我们将得到自开始日期以来的正确周数:

In [10]: (x["date"].diff().dt.days.cumsum() - 2) // 7 + 1
Out[10]:
0     NaN
1    52.0
2    52.0
3    54.0
Name: date, dtype: float64

请注意,我们加 1 是因为(我假设)您是从 1 开始计数的——即 2014-01-01 对您来说是第 1 周,而不是第 0 周。

最后,.fillna只是为了处理那个NaT(当我们开始算术时它变成了NaN)。您使用 .fillna(value)NaN 填充为 value:

In [11]: ((x["date"].diff().dt.days.cumsum() - 2) // 7 + 1).fillna(1)
Out[11]:
0     1.0
1    52.0
2    52.0
3    54.0
Name: date, dtype: float64

最后使用 .astype() 将列转换为整数而不是浮点数。