【问题标题】:slicing pandas dataframe on date range在日期范围内切片熊猫数据框
【发布时间】:2012-07-06 19:44:10
【问题描述】:

我正在使用 pandas 来分析财务记录。

我有一个来自 csv 文件的DataFrame,如下所示:

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 800 entries, 2010-10-27 00:00:00 to 2011-07-12 00:00:00
Data columns:
debit                      800  non-null values
transaction_type           799  non-null values
transaction_date_raw       800  non-null values
credit                     800  non-null values
transaction_description    800  non-null values
account_number             800  non-null values
sort_code                  800  non-null values
balance                    800  non-null values
dtypes: float64(3), int64(1), object(4)

我正在根据交易金额选择一个子集:

c1 = df['credit'].map(lambda x: x > 1000)
milestones = df[c1].sort()

并希望根据里程碑之间的日期创建原始 df 的切片:

delta = dt.timedelta(days=1)
for i in range(len(milestones.index)-1):
        start = milestones.index[i].date()
        end = milestones.index[i+1].date() - delta
        rng = date_range(start, end)

这会生成一个新系列,其中包含我的里程碑之间的日期。

<class 'pandas.tseries.index.DatetimeIndex'>
[2010-11-29 00:00:00, ..., 2010-12-30 00:00:00]
Length: 32, Freq: D, Timezone: None

我已经按照几种方法使用这些新系列 (rng) 对我的 df 进行切片,但都失败了:

df.ix[start:end] or
df.ix[rng]

这会引发:IndexError: invalid slice

df.reindex(rng) or df.reindex(index=rng)

引发:异常:重新索引仅对具有唯一值的索引对象有效

x = [v for v in rng if v in df.index]
df[x]
df.ix[x]
df.index[x]

这也会引发无效切片,因此也会:

df.truncate(start, end)

我是 pandas 的新手,我正在关注 Oreilly 早期发布的这本书,并且非常喜欢它。任何指针将不胜感激。

【问题讨论】:

    标签: python time-series pandas


    【解决方案1】:

    看起来您在非唯一索引处理中遇到了几个已知错误:

    https://github.com/pydata/pandas/issues/1201/

    https://github.com/pydata/pandas/issues/1587/

    错误修复版本即将发布,请在一周左右查看 pandas 网站或 PyPI。

    谢谢

    【讨论】:

    • 我找到了一个“hackish”解决方案,见上文
    【解决方案2】:

    我已经设法规避了上面突出显示的一些问题,这里有一个“解决方案”,直到解决常舍提到的错误。

    我像以前一样从原始的 TimeSeries 索引 DataFrame 开始。我对 df 进行排序,这会按日期对记录进行排序(使用 TimeSeries 索引)。

    df = df.sort()
    

    排序后,我将 df.index 替换为数字索引

    df.index = range(len(df))
    

    我随后像以前一样提取我的里程碑,不同的是现在这些将有一个正整数索引,并创建该索引的列表:

    milestones_list = milestones_df.index.tolist()
    

    并使用数字索引从原始 df 中提取我的里程碑之间的数据,如下所示:

    datasets = {}
        for milestone in milestones_list:
            milestone_index = milestones_list.index(milestone)
            print "milestone {0} index {1}".format(milestone, milestone_index)
            if milestone_index < len(milestones_list) -1:
                x = df[milestones_df.index[milestone_index]:milestones_df.index[milestone_index+1]]
            else:
                x = df[milestones_df.index[milestone_index]:df.index.max()]
    
            n = str(int(x.index.min())) +'-'+  str(int(x.index.max()))
            datasets[n] = x
    

    这会为每个里程碑时间间隔创建一个带有 DataFrames 的字典,命名为它们所代表的索引间隔。

    print datasets.keys()
    ['592-650', '448-527', '382-447', '264-318', '319-381', '118-198', '528-591', '728-798', '54-117', '199-263', '651-727']
    

    虽然诚然不是理想的解决方案,但我希望它可以帮助遇到类似问题的人。

    【讨论】:

      猜你喜欢
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 1970-01-01
      • 2021-03-27
      相关资源
      最近更新 更多