【问题标题】:Fill missing days in timeseries (with duplicate keys)填写时间序列中缺失的日期(使用重复键)
【发布时间】:2013-10-21 13:56:52
【问题描述】:

这是我在 Pandas 中尝试做的事情:

  • 加载包含特定日期股票信息的 CSV 文件
  • date列中查找最早和最晚的日期
  • 创建一个新的数据框,填充最早和最晚之间的所有日期(NaN 或类似“缺失”的所有列都可以)

目前看起来是这样的:

import pandas as pd
import dateutil

df = pd.read_csv("https://dl.dropboxusercontent.com/u/84641/temp/berkshire_new.csv")
df['date'] = df['date'].apply(dateutil.parser.parse)
new_date_range = pd.date_range(df['date'].min(), df['date'].max())
df = df.set_index('date')
df.reindex(new_date_range)

不幸的是,这引发了以下我不太明白的错误:

ValueError: Shape of passed values is (3, 4825), indices imply (3, 4384)

我已经尝试了十几种这样的变体 - 没有任何运气。任何帮助将不胜感激。

编辑:

经过进一步调查,问题似乎是由重复索引引起的。 CSV 确实包含每个日期的多个条目,这可能是导致错误的原因。

这个问题仍然很重要:尽管每个日期都有重复的条目,但我怎样才能填补两者之间的空白?

【问题讨论】:

  • 哪一行抛出异常?已经是read_csv了吗?
  • @Alfe 不,引发错误的行是带有reindex 的行。我还在问题中添加了更多信息,因为我认为问题是由 CSV 中的重复键引起的。

标签: python pandas


【解决方案1】:

所以你在考虑符号、日期、动作时有重复。

In [99]: df.head(10)
Out[99]: 
  symbol                date      change    action
0    FDC 2001-08-15 00:00:00   15.069360       new
1    GPS 2001-08-15 00:00:00   19.653780       new
2    HON 2001-08-15 00:00:00    8.604316       new
3    LIZ 2001-08-15 00:00:00    6.711568       new
4    NKE 2001-08-15 00:00:00   22.686257       new
5    ODP 2001-08-15 00:00:00    5.686902       new
6    OSI 2001-08-15 00:00:00    5.893340       new
7    USB 2001-08-15 00:00:00   15.694478       new
8    NEE 2001-11-15 00:00:00  100.000000       new
9    GPS 2001-11-15 00:00:00  142.522231  increase

创建新的日期索引

In [102]: idx = pd.date_range(df.date.min(),df.date.max())

In [103]: idx
Out[103]: 
<class 'pandas.tseries.index.DatetimeIndex'>
[2001-08-15 00:00:00, ..., 2013-08-15 00:00:00]
Length: 4384, Freq: D, Timezone: None

这将按符号和动作分组 然后重新索引设置为完整日期(idx) 选择剩下的唯一列(更改) 现在索引是符号/日期

In [100]: df.groupby(['symbol','action']).apply(
              lambda x: x.set_index('date').reindex(idx)
                  )['change'].reset_index(level=1).head()

Out[100]: 
                     action  change
symbol                             
ADM    2001-08-15  decrease     NaN
       2001-08-16  decrease     NaN
       2001-08-17  decrease     NaN
       2001-08-18  decrease     NaN
       2001-08-19  decrease     NaN

In [101]: df.groupby(['symbol','action']).apply(lambda x: x.set_index('date').reindex(idx))['change'].reset_index(level=1)
Out[101]: 
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 977632 entries, (ADM, 2001-08-15 00:00:00) to (svm, 2013-08-15 00:00:00)
Data columns (total 2 columns):
action    977632  non-null values
change    490  non-null values
dtypes: float64(1), object(1)

然后您可以向前填写或填写您需要的任何内容。仅供参考,不确定您将如何处理此操作,但这不是一种非常常见的操作类型,因为您的数据大多为空。

【讨论】:

  • 谢谢!这几乎是我需要的。没想到会这么复杂 :) 我还需要为动作设置一个 NaN,但还没想好怎么做。
【解决方案2】:

我现在遇到了类似的问题,我认为您不应该使用 reindex,而是使用 asfreqresample 之类的东西。

你不需要创建索引,你愿意。

【讨论】:

    猜你喜欢
    • 2018-05-21
    • 1970-01-01
    • 2011-04-03
    • 2018-04-24
    • 1970-01-01
    • 2017-05-06
    • 2018-06-24
    • 2020-02-06
    相关资源
    最近更新 更多