【问题标题】:How to retrieve a certain day of the month for each row based on a dataframe value?如何根据数据框值检索每一行的一个月中的某一天?
【发布时间】:2021-11-29 20:26:31
【问题描述】:

我正在尝试用更动态/数据驱动的 Python 脚本替换一些与时区更改相关的硬编码 SQL 查询。我有一个看起来像下面这个电子表格的数据集。 WEEK_START/DAY/MONTH 是夏令时开始的周、日和月(例如,堪培拉从四月的第一个星期日开始,而维也纳是三月的最后一个星期日)。结束变量格式相同,结束时显示。

Dataset

这就是问题所在。我已经看到了针对特定用例的解决方案,例如这个月的最后一个星期日:

current_year=today.year
current_month=today.month
current_day=today.day

month = calendar.monthcalendar(current_year, current_month)
day_of_month = max(month[-1][calendar.SUNDAY], month[-2][calendar.SUNDAY])
print(day_of_month)
31

这告诉我这个月的最后一天是 31 号。我可以调整给定月份/场景的属性,但是如何为每一行(城市)创建一个 来检索每一行?也就是说,在不同日期更改时间的几个城市?我想如果我可以在 apply 函数中设置 day_of_month 中的属性,它会起作用,但是当我执行类似 weekday='SUNDAY' 之类的操作时,它会返回错误,因为字符串 'SUNDAY' 当然与日历属性 SUNDAY 不同。我的 SQL 查询按在同一天发生变化的城市分组,但理想情况下,任何人都可以根据需要编辑加载上述数据集的 CSV,然后每天运行一次脚本以查看今天是否介于夏令时。未来我们可能会增加新的城市。我有信心做到这一点,但对如何检索给定年份的日期非常迷茫。

我的备用,弹性较差的选项是查看潜在日期的不同列表(3 月的最后一个星期日,4 月的第一个星期日等),编写代码以预先检索每个日期(如上面的 sn-p以上),并以这种方式分配日期。我说这不太灵活,因为如果添加的城市不适合现有组以进行时间更改,则代码也需要更改。

那么stackoverflow,有没有办法通过apply或类似的东西在pandas中以数据驱动的方式做到这一点?提前致谢。

【问题讨论】:

  • 我认为,一般来说,获取 DST 过渡日期的“数据驱动”方式是为城市分配时区;然后您可以从the IANA database 中提取每年的日期。

标签: python pandas dataframe csv datetime


【解决方案1】:

基本上,我认为您拥有大部分所需的东西。只需将 WEEK_START / WEEK_END 列 {-1, 1} 映射到一个月的最后一天或第一天,将其全部放入一个函数中,然后将 apply 映射到每一行。例如:

import calendar
import operator
import pandas as pd

def get_date(year: int, month: int, dayname: str, first=-1) -> pd.Timestamp:
    """
    get the first or last day "dayname" in given month and year.
    returns last by default.
    """
    daysinmonth = calendar.monthcalendar(year, month)
    getday = operator.attrgetter(dayname.upper())
    if first == 1:
        day = daysinmonth[0][getday(calendar)] 
    else:
        day = max(daysinmonth[-1][getday(calendar)], daysinmonth[-2][getday(calendar)])
    return pd.Timestamp(year, month, day)


year = 2021 # we need a year...

df['date_start'] = df.apply(lambda row: get_date(year,
                                                 row['MONTH_START'],
                                                 row['DAY_START'],
                                                 row['WEEK_START']), # selects first or last
                            axis=1) # to each row

df['date_end'] = df.apply(lambda row: get_date(year,
                                               row['MONTH_END'],
                                               row['DAY_END'],
                                               row['WEEK_END']), 
                          axis=1)

给你样本数据

df[['CITY', 'date_start', 'date_end']]
               CITY date_start   date_end
0          Canberra 2021-04-04 2021-10-03
1         Melbourne 2021-04-04 2021-10-03
2            Sydney 2021-04-04 2021-10-03
3         Kitzbuhel 2021-03-28 2021-10-31
4            Vienna 2021-03-28 2021-10-31
5           Antwerp 2021-03-28 2021-10-31
6          Brussels 2021-03-28 2021-10-31
7  Louvain-la-Neuve 2021-03-28 2021-10-31

一旦您开始处理时区和 DST 转换,您可能也会对 Q:Is there a way to infer in Python if a date is the actual day in which the DST (Daylight Saving Time) change is made? 感兴趣。

【讨论】:

  • 这太完美了,谢谢!我很欣赏解释和 cmets,以及其他帖子的链接。这可能是一个改变游戏规则的包。
  • @ariana20 很高兴我能提供帮助。请记住,熊猫有自己的日期时间数据类型,最好使用它。因此,如果在 pandas 中使用 datetime,请务必检查是否有特定于 pandas 的解决方案。这些在许多情况下更有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多