python - Pandas 将 nan 放在特定行('Feb-29')并将剩余的行向上移动
问题描述
我有一个熊猫数据框,其中包含几年的时间序列数据作为列。每个都从 11 月开始,到次年结束。我正在尝试在非闰年处理 NaN。可以使用以下内容重新创建结构:
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
ndays = 151
sdates = [(datetime(2019,11,1) + timedelta(days=x)).strftime("%b-%d") for x in range(ndays)]
columns=list(range(2016,2021))
df = pd.DataFrame(np.random.randint(0,100,size=(ndays, len(columns))), index=sdates, columns=columns)
df.loc["Feb-29",2017:2019] = np.nan
df.loc["Feb-28":"Mar-01"]
Out[61]:
2016 2017 2018 2019 2020
Feb-28 36 59.0 74.0 19.0 24
Feb-29 85 NaN NaN NaN 6
Mar-01 24 75.0 49.0 99.0 82
我想要做的是仅删除“Feb-29”NaN 数据(在非闰年),然后将这些列中的数据向上移动一行,让闰年保持原样。像这样,Mar-01 和随后的行在 2017 年到 2019 年向上移动:
2016 2017 2018 2019 2020
Feb-28 36 59.0 74.0 19.0 24
Feb-29 85 75.0 49.0 99.0 6
Mar-01 24 42.0 21.0 41.0 82
我不在乎“Mar-01”数据将被标记为“Feb-29”,因为最终我将用整数索引替换字符串日期索引。
请注意,我没有在示例中包含此内容,但在我不想删除的不同行中,我在数据帧的开头和结尾有 NaN(即,我不能只删除所有 NaN 数据,我需要定位“2月29日”具体)
解决方案
听起来您实际上并不想将日期向上移动,而是根据一年中的日期正确编号?如果是这样,这将起作用:
首先,使 DataFrame 长而不是宽:
df = pd.DataFrame(
{
"2016": {"Feb-28": 36, "Feb-29": 85, "Mar-01": 24},
"2017": {"Feb-28": 59.0, "Feb-29": None, "Mar-01": 75.0},
"2018": {"Feb-28": 74.0, "Feb-29": None, "Mar-01": 49.0},
"2019": {"Feb-28": 19.0, "Feb-29": None, "Mar-01": 99.0},
"2020": {"Feb-28": 24, "Feb-29": 6, "Mar-01": 82},
}
)
df = (
df.melt(ignore_index=False, var_name="year", value_name="value")
.reset_index()
.rename(columns={"index": "month-day"})
)
df
month-day year value
0 Feb-28 2016 36.0
1 Feb-29 2016 85.0
2 Mar-01 2016 24.0
3 Feb-28 2017 59.0
4 Feb-29 2017 NaN
5 Mar-01 2017 75.0
6 Feb-28 2018 74.0
7 Feb-29 2018 NaN
8 Mar-01 2018 49.0
9 Feb-28 2019 19.0
10 Feb-29 2019 NaN
11 Mar-01 2019 99.0
12 Feb-28 2020 24.0
13 Feb-29 2020 6.0
14 Mar-01 2020 82.0
然后删除包含无效日期的行并获取剩余天数的年份:
df["date"] = pd.to_datetime(
df.apply(lambda row: " ".join(row[["year", "month-day"]]), axis=1), errors="coerce",
)
df = df[df["date"].notna()]
df["day_of_year"] = df["date"].dt.dayofyear
df
month-day year value date day_of_year
0 Feb-28 2016 36.0 2016-02-28 59
1 Feb-29 2016 85.0 2016-02-29 60
2 Mar-01 2016 24.0 2016-03-01 61
3 Feb-28 2017 59.0 2017-02-28 59
5 Mar-01 2017 75.0 2017-03-01 60
6 Feb-28 2018 74.0 2018-02-28 59
8 Mar-01 2018 49.0 2018-03-01 60
9 Feb-28 2019 19.0 2019-02-28 59
11 Mar-01 2019 99.0 2019-03-01 60
12 Feb-28 2020 24.0 2020-02-28 59
13 Feb-29 2020 6.0 2020-02-29 60
14 Mar-01 2020 82.0 2020-03-01 61
推荐阅读
- visual-c++ - 为什么 xmm11 在优化代码中不保留交叉调用?
- ios - Swift:使用present时无法在视图控制器之间传递数据
- python - 如何使用 Jenkins 中分离的变量、关键字和测试文件构建 Robot Framework 项目
- r - 使用 rollapply 计算每周百分比变化
- identityserver4 - 解密 Identity Server 中的共享密钥
- javascript - 为什么控制台显示 js 代码,即使我没有在单独的文件中?
- java - 使用 Spring Boot 和 Thymeleaf 上传多个文件
- css - React native:试图在滚动时隐藏搜索栏
- javascript - 如果目标平台是 Raspberry Pi OS (arm),则禁用代码行 (JavaScript/QML)
- angular - 带有 AAD 的 Azure Function Cors