相关文章推荐
至今单身的橙子  ·  使用aws ...·  1 年前    · 
重感情的草稿本  ·  如何在 Python ...·  1 年前    · 

python pandas数据帧按日期条件切分

58 人关注

我能够使用python的数据时间对象来读取和切分pandas的数据框架,但是我被迫只使用 现有日期 在索引中。 例如,这样就可以了。

<class 'pandas.core.frame.DataFrame'> DatetimeIndex: 252 entries, 2010-12-31 00:00:00 to 2010-04-01 00:00:00 Data columns: Adj Close 252 non-null values dtypes: float64(1) >>> st = datetime.datetime(2010, 12, 31, 0, 0) >>> en = datetime.datetime(2010, 12, 28, 0, 0) >>> data[st:en] Adj Close 2010-12-31 593.97 2010-12-30 598.86 2010-12-29 601.00 2010-12-28 598.92

然而,如果我使用DF中不存在的开始或结束日期,我得到python KeyError。

我的问题:我如何查询数据框架对象的日期范围;即使开始和结束日期不存在于数据框架中。 pandas是否允许基于范围的切分?

我使用的是pandas 0.10.1版

1 个评论
现在,在Pandas 0.20.3上,我实际上没有得到任何 KeyErrors ,即使在帧的索引之外使用 datetimes 也是如此。所以目前最简单的解决方案就是像上面的OP那样做! df[dt.datetime(1914, 1, 1):] 给我的是2010年的日期。
python
dataframe
pandas
Rishabh Sagar
Rishabh Sagar
发布于 2013-04-24
6 个回答
waitingkuo
waitingkuo
发布于 2022-06-05
已采纳
0 人赞同

先用 searchsorted 找到最接近的次数,然后用它来切分。

In [15]: df = pd.DataFrame([1, 2, 3], index=[dt.datetime(2013, 1, 1), dt.datetime(2013, 1, 3), dt.datetime(2013, 1, 5)])
In [16]: df
Out[16]: 
2013-01-01  1
2013-01-03  2
2013-01-05  3
In [22]: start = df.index.searchsorted(dt.datetime(2013, 1, 2))
In [23]: end = df.index.searchsorted(dt.datetime(2013, 1, 4))
In [24]: df.iloc[start:end]
Out[24]: 
2013-01-03  2
    
如果我复制粘贴你的例子,它可以正常工作。 但是我程序中的开始和结束变量,总是默认为数据框架的长度!我做错了什么?- pastebin.com/raw.php?i=hfpHqF7s
看来你应该把你的 DataFrame 按升序排列。
谢谢,当数据以升序排序时,它是有效的。
请注意, searchsorted 不再定义于DataFrame或Series,见 this question .
Dan Allan
Dan Allan
发布于 2022-06-05
0 人赞同

简单回答。对你的数据进行分类( data.sort() ),然后我想一切都会按照你所期望的方式进行。

是的,你可以使用DataFrame中不存在的数据时间进行切分。比如说。

In [12]: df
Out[12]: 
2013-04-20  1.120024
2013-04-21 -0.721101
2013-04-22  0.379392
2013-04-23  0.924535
2013-04-24  0.531902
2013-04-25 -0.957936
In [13]: df['20130419':'20130422']
Out[13]: 
2013-04-20  1.120024
2013-04-21 -0.721101
2013-04-22  0.379392

正如你所看到的,你甚至不需要建立日期时间对象;字符串也可以。

因为你的索引中的日期时间是不连续的,所以行为很奇怪。如果我们把我这里的例子的索引洗一下...

In [17]: df
Out[17]: 
2013-04-22  1.120024
2013-04-20 -0.721101
2013-04-24  0.379392
2013-04-23  0.924535
2013-04-21  0.531902
2013-04-25 -0.957936

...并采取同样的切片,我们得到一个不同的结果。它返回范围内的第一个元素,在范围外的第一个元素处停止。

In [18]: df['20130419':'20130422']
Out[18]: 
2013-04-22  1.120024
2013-04-20 -0.721101
2013-04-24  0.379392

这可能不是有用的行为。如果你想选择日期范围,先按日期排序是否有意义?

df.sort_index()
    
当我试图这样做时,我得到了一个python异常。 TimeSeriesError。部分索引只对有序的时间序列有效。
例外是不言自明的--我漏掉了对数据的排序,:(--谢谢,如你上面所示,基于文本的切片工作如预期。 但是我使用了searchsorted函数,因为程序中的日期已经是数据时间对象。
df['20130419':'20130422']是个例外!甚至对稀疏的数据也有效(例如,指定一个不存在于索引中的日期)。谢谢你!
请注意,data.sort()现在已经废弃了。替换这个应用程序的是data.sort_index() -- http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort_index.html
谢谢你,Kapocsi。已更新。
watsonic
watsonic
发布于 2022-06-05
0 人赞同

你可以用一个简单的面具来完成这个任务。

date_mask = (data.index > start) & (data.index < end)
dates = data.index[date_mask]
data.ix[dates]

顺便说一下,这也适用于分层索引。在这种情况下,data.index将被替换为data.index.levels[0]或类似的内容。

这个答案需要更多的赞许。我已经找了几个星期了!
R. Cox
R. Cox
发布于 2022-06-05
0 人赞同

我在使用其他方法时遇到了困难,但我发现以下方法对我很有效。

# Set the Index to be the Date
df['Date'] = pd.to_datetime(df['Date_1'], format='%d/%m/%Y')
df.set_index('Date', inplace=True)
# Sort the Data
df = df.sort_values('Date_1')
# Slice the Data
From = '2017-05-07'
To   = '2017-06-07'
df_Z = df.loc[From:To,:]
    
你不需要超过instr.loc[From:To]让我猜,你也是R的用户?
fega_zero
fega_zero
发布于 2022-06-05
0 人赞同
target_date = pd.Timestamp('2020-05-10')
df[df['DATE'].dt.date == (dt.date(target_date.year, target_date.month, target_date.day))]

这一行将让你选择所有符合条件的日期,如果你不需要设置 "日期栏 "作为索引的话。

看起来不错。我只是想指出,df[df['DATE'].dt.date中的dt与dt.date中的dt不同,后者必须通过导入datetime作为dt来暴露,以避免得到错误。
rachwa
rachwa
发布于 2022-06-05
0 人赞同

给出一个数据框架 df ,其中要查询的日期在索引中,你可以使用 query :

In [5]: df = pd.DataFrame({'Close': {'2010-12-31': 593.97, '2010-12-30': 598.86, '2010-12-29': 601.0, '2010-12-28': 598.92}})
In [6]: df
Out[6]: 
             Close
2010-12-31  593.97
2010-12-30  598.86
2010-12-29  601.00
2010-12-28  598.92
In [7]: df.query('"2010-12-01" < index <= "2010-12-29"')
Out[7]: 
             Close