选择由 DatetimeIndex 索引的 Pandas DataFrame 的子集和时间戳列表
Posted
技术标签:
【中文标题】选择由 DatetimeIndex 索引的 Pandas DataFrame 的子集和时间戳列表【英文标题】:Selecting a subset of a Pandas DataFrame indexed by DatetimeIndex with a list of TimeStamps 【发布时间】:2012-08-13 01:35:06 【问题描述】:我有一只大熊猫DataFrame
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 3425100 entries, 2011-12-01 00:00:00 to 2011-12-31 23:59:59
Data columns:
sig_qual 3425100 non-null values
heave 3425100 non-null values
north 3425099 non-null values
west 3425097 non-null values
dtypes: float64(4)
我使用.ix[start_datetime:end_datetime]
选择了DataFrame
的一个子集,并将其传递给peakdetect function,它在两个单独的列表中返回局部最大值和最小值的索引和值。我提取最大值的索引位置并使用DataFrame.index
我得到一个熊猫时间戳列表。
然后我尝试通过将时间戳列表传递给.ix[]
来提取大型 DataFrame 的相关子集,但它似乎总是返回一个空的DataFrame
。我可以遍历时间戳列表并从DataFrame
中获取相关行,但这是一个漫长的过程,我认为ix[]
应该根据the docs 接受值列表?
(虽然我看到 Pandas 0.7 的示例使用 numpy.ndarray
或 numpy.datetime64
)
更新: 下面选择了一小段 8 秒的 DataFrame 子集,# 行显示了一些值:
y = raw_disp['heave'].ix[datetime(2011,12,30,0,0,0):datetime(2011,12,30,0,0,8)]
#csv representation of y time-series
2011-12-30 00:00:00,-310.0
2011-12-30 00:00:01,-238.0
2011-12-30 00:00:01.500000,-114.0
2011-12-30 00:00:02.500000,60.0
2011-12-30 00:00:03,185.0
2011-12-30 00:00:04,259.0
2011-12-30 00:00:04.500000,231.0
2011-12-30 00:00:05.500000,139.0
2011-12-30 00:00:06.500000,55.0
2011-12-30 00:00:07,-49.0
2011-12-30 00:00:08,-144.0
index = y.index
<class 'pandas.tseries.index.DatetimeIndex'>
[2011-12-30 00:00:00, ..., 2011-12-30 00:00:08]
Length: 11, Freq: None, Timezone: None
#_max returned from the peakdetect function, one local maxima for this 8 seconds period
_max = [[5, 259.0]]
indexes = [x[0] for x in _max]
#[5]
timestamps = [index[z] for z in indexes]
#[<Timestamp: 2011-12-30 00:00:04>]
print raw_disp.ix[timestamps]
#Empty DataFrame
#Columns: array([sig_qual, heave, north, west, extrema], dtype=object)
#Index: <class 'pandas.tseries.index.DatetimeIndex'>
#Length: 0, Freq: None, Timezone: None
for timestamp in timestamps:
print raw_disp.ix[timestamp]
#sig_qual 0
#heave 259
#north 27
#west 132
#extrema 0
#Name: 2011-12-30 00:00:04
更新 2:
我created a gist,这实际上是有效的,因为当从 csv 加载数据时,时间戳的索引列存储为对象的 numpy 数组,这些对象看起来是字符串。与我自己的代码中索引的类型为 <class 'pandas.tseries.index.DatetimeIndex'>
且每个元素的类型为 <class 'pandas.lib.Timestamp'>
不同,我认为传递 pandas.lib.Timestamp
的列表与传递单个时间戳的工作方式相同,这会被视为错误吗?
如果我使用索引作为字符串列表创建原始DataFrame
,则使用字符串列表进行查询可以正常工作。但它确实会显着增加 DataFrame 的字节大小。
更新 3: 该错误似乎只发生在非常大的 DataFrame 上,我在不同大小的 DataFrame 上重新运行了代码(下面的评论中有一些细节),它似乎发生在超过 270 万条记录的 DataFrame 上。使用字符串而不是时间戳可以解决问题,但会增加内存使用量。
已修复 在最新的 github master (18/09/2012) 中,请参阅页面底部 Wes 的评论。
【问题讨论】:
【参考方案1】:df.ix[my_list_of_dates] 应该可以正常工作。
In [193]: df
Out[193]:
A B C D
2012-08-16 2 1 1 7
2012-08-17 6 4 8 6
2012-08-18 8 3 1 1
2012-08-19 7 2 8 9
2012-08-20 6 7 5 8
2012-08-21 1 3 3 3
2012-08-22 8 2 3 8
2012-08-23 7 1 7 4
2012-08-24 2 6 0 6
2012-08-25 4 6 8 1
In [194]: row_pos = [2, 6, 9]
In [195]: df.ix[row_pos]
Out[195]:
A B C D
2012-08-18 8 3 1 1
2012-08-22 8 2 3 8
2012-08-25 4 6 8 1
In [196]: dates = [df.index[i] for i in row_pos]
In [197]: df.ix[dates]
Out[197]:
A B C D
2012-08-18 8 3 1 1
2012-08-22 8 2 3 8
2012-08-25 4 6 8 1
【讨论】:
感谢您的示例,这是我对它应该如何工作的理解,我现在提供了一个示例,说明它在我原来的问题中是如何失败的。 你用的是什么版本的熊猫?可以分享 raw_disp 吗?对我来说update
工作正常,y.ix[timestamps](y 有 DateTimeIndex)给出了预期的输出(我当然不能做 raw_disp.ix[timestamps],因为 raw_disp 不可用。)
Pandas 版本 0.8.1,我一直在尝试在较小的 DataFrame 上重现该错误,但它没有发生。当我在超过 300 万行的大型 DataFrame 上尝试它时,我得到了一个 Empty DataFrame。我已经成功地在 2888264 行的 DataFrame 上重现了该错误,但它在 2665621 行的 DataFrame 上运行良好。如果其他人希望复制它,我可以上传大的 DataFrame。
我尝试使用index = pandas.date_range('03/06/2000 00:00', periods=3e6, freq='s')
复制此内容,df = pandas.DataFrame(np.random.randn(3e6, 4), columns=list('ABCD'), index=index)
效果很好。您能否在 GitHub (github.com/pydata/pandas/issues) 上发布问题 - 使用重现问题的代码?
今天 (9/18) 已在 GitHub 上修复以上是关于选择由 DatetimeIndex 索引的 Pandas DataFrame 的子集和时间戳列表的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Pandas 中使用 datetimeindex 属性选择对 df 的观察?
pandas使用pd.DatetimeIndex函数将混合格式的日期数据数据转化为时间索引数据DatetimeIndex通过index参数为Series数据指定时间对象索引
pandas使用pd.DatetimeIndex函数将混合格式的日期数据数据转化为时间索引数据DatetimeIndex通过index参数为Series数据指定时间对象索引
pandas使用pd.DatetimeIndex函数将字符串日期列表数据转化为时间索引数据DatetimeIndex
无法使用这些索引器对 DatetimeIndex 进行位置索引
pandas使用pd.DatetimeIndex函数将混合格式的日期数据(包含字符串datetime对象pd.Timestamp)数据转化为时间索引数据DatetimeIndex