You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为DataFrame中每个单元生成无缺失值的季度时间列

为多ID数据集生成无缺失的季度时间列

问题

我们有一个包含25个国家人均GDP的数据集,需要为每个id(1至25)生成对应time(1至61)的季度时间列(范围1993Q1至2008Q1),但现有代码生成的DataFrame中dates列存在大量NaT缺失值。

原代码

import requests
import zipfile
import io
import pandas as pd
import numpy as np

from datetime import datetime
from dateutil import relativedelta

url = 'http://qed.econ.queensu.ca/jae/datasets/hsiao003/hcw-data.zip'
filename = 'hcw-data.txt'

r = requests.get(url)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall()


df = (pd.read_csv(url, sep='\t+', header=None, engine='python')
        .stack().rename_axis(['time', 'id']).rename('gdp').reset_index()
        .assign(time=lambda x: x['time'] + 1))
df['id'] = df['id']+1

df = df[['id', 'time', 'gdp']]

df = df.sort_values(by=['id', 'time'])

df = df.reset_index()
start_date = datetime.strptime("1993-01-01", "%Y-%m-%d")

# periods means how many dates you want
date_list = pd.date_range(start_date, periods=61, freq='Q')

df['dates'] = pd.DataFrame({'dates': date_list})

错误现象

生成的DataFrame中dates列仅前61行有值,后续行全部为NaT:

index  id  time     gdp      dates
0         0   1     1  0.0620 1993-03-31
1        25   1     2  0.0590 1993-06-30
2        50   1     3  0.0580 1993-09-30
3        75   1     4  0.0620 1993-12-31
4       100   1     5  0.0790 1994-03-31
    ...  ..   ...     ...        ...
1520   1424  25    57  0.1110        NaT
1521   1449  25    58  0.1167        NaT
1522   1474  25    59  0.1002        NaT
1523   1499  25    60  0.1017        NaT
1524   1524  25    61  0.1238        NaT

[1525 rows x 5 columns]

解决方案

问题根源

原代码生成的date_list仅包含61个日期,但数据集共有25个id×61个时间点=1525行。直接赋值时,只有前61行能匹配到日期,剩余行因无对应数据填充为NaT。此外,原代码还存在数据加载错误:用pd.read_csv(url)读取zip链接而非提取后的本地文本文件,会导致数据结构异常。

修改后的完整代码

import requests
import zipfile
import io
import pandas as pd
import numpy as np

from datetime import datetime

url = 'http://qed.econ.queensu.ca/jae/datasets/hsiao003/hcw-data.zip'
filename = 'hcw-data.txt'

# 下载并解压数据
r = requests.get(url)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall()

# 加载并整理数据集
df = (pd.read_csv(filename, sep='\t+', header=None, engine='python')  # 读取本地解压后的文件
        .stack().rename_axis(['time', 'id']).rename('gdp').reset_index()
        .assign(time=lambda x: x['time'] + 1))
df['id'] = df['id'] + 1
# 排序并清理冗余索引
df = df[['id', 'time', 'gdp']].sort_values(by=['id', 'time']).reset_index(drop=True)

# 生成基础季度日期序列(1993Q1至2008Q1共61个季度)
start_date = datetime.strptime("1993-01-01", "%Y-%m-%d")
date_list = pd.date_range(start_date, periods=61, freq='Q')

# 为每个id重复日期序列,填充所有行
df['dates'] = np.tile(date_list, 25)

# 可选:将日期转换为"1993Q1"格式的季度字符串
df['quarter_label'] = df['dates'].dt.to_period('Q')

核心修改说明

  1. 修复数据加载:将pd.read_csv(url)改为读取本地文件filename,确保正确解析文本数据。
  2. 批量生成重复日期:用np.tile(date_list, 25)将61个季度日期重复25次,刚好匹配1525行数据,保证每个id的time1-61都对应正确日期。
  3. 清理冗余列:用reset_index(drop=True)移除不必要的原索引列,简化DataFrame结构。
  4. 可选格式优化:通过dt.to_period('Q')将日期转换为直观的季度标签(如1993Q1),方便后续分析。

内容的提问来源于stack exchange,提问作者Jared Greathouse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 14:45:16