pandas 获取DataFrame中存在的上一个和下一个索引值

xu3bshqb  于 2023-02-27  发布在  其他
关注(0)|答案(4)|浏览(232)

假设我有一个DataFrame

df = pd.DataFrame(dict(vals=np.random.randint(0, 10, 10)),
                  index=pd.date_range('20170401', '20170410'))

>>> df
               vals
2017-04-01     9
2017-04-02     8
2017-04-03     4
2017-04-04     5
2017-04-05     9
2017-04-06     9
2017-04-07     5
2017-04-08     3
2017-04-09     3
2017-04-10     1

以及我知道在我的索引中但不知道位置的特定日期,例如

cur_dt = df.index[np.random.randint(0, df.index.size)]

>>> cur_dt
Timestamp('2017-04-05 00:00:00', freq='D')

给定cur_dt,我想确定索引中的前一个和后一个值是什么,如果cur_dt是索引中的第一个(最后一个)值,那么前一个(后一个)元素应该是cur_dt本身。

总结一下,我的问题是,在给定当前值的情况下,查找索引中的上一个值和下一个值(如果当前值是端点,则查找当前值本身)的最简单方法是什么?

我目前的方法似乎相当迂回,这也是我问这个问题的动机。

cur_iloc = df.index.get_loc(cur_dt)
prev = cur_dt if cur_iloc == 0 else df.index[cur_iloc-1]
next = cur_dt if cur_iloc == df.index.size-1 else df.index[cur_iloc+1]

>>> prev
Timestamp('2017-04-04 00:00:00', freq='D')
>>> next
Timestamp('2017-04-06 00:00:00', freq='D')

如果没有更直接的方法,那么我道歉,我想象能够只是“移动”我的指数从我的当前值一次向前和一次向后(与一些很好的处理端点),但不确定这是否可能。

uplii1fm

uplii1fm1#

假设索引已经排序,尝试使用numpy.searchsorted

源数据集:

In [185]: df
Out[185]:
            vals
2017-04-01     5
2017-04-02     3
2017-04-03     9
2017-04-04     8
2017-04-05     1
2017-04-06     0
2017-04-07     4
2017-04-08     5
2017-04-09     1
2017-04-10     8

In [186]: cur_dt
Out[186]: Timestamp('2017-04-02 00:00:00', freq='D')

解决方案:

In [187]: idx = np.searchsorted(df.index, cur_dt)

In [188]: df.index[max(0, idx-1)]
Out[188]: Timestamp('2017-04-01 00:00:00', freq='D')

In [189]: df.index[min(idx+1, len(df)-1)]
Out[189]: Timestamp('2017-04-03 00:00:00', freq='D')
siotufzp

siotufzp2#

重置索引,然后使用布尔逻辑标识cur_dt的位置,如下所示:

df = df.reset_index()
cur_dt_index = df.index[np.random.randint(0, df['index'].size)]
previous = max(cur_dt_index-1, 0)
next = min(cur_dt_index + 1, df.shape[0])
46qrfjad

46qrfjad3#

创建一个新的时间序列ts,其索引与df相同,df将存储以前的索引(并确保ts的索引已排序),然后只需将ts移位1。

ts=pd.Series(df.index,index=df.index).sort_index().shift(1)

(This如果只需要查找一次上一个索引,则可能会比较慢,但如果需要多次查找,则会比较快。)

jchrr9hc

jchrr9hc4#

def get_next_idx(df, current_idx):
    after = df.truncate(before=current_idx).iloc[1:]
    return after.index[0] if 0 < len(after) else None

def get_prev_idx(df, current_idx):
    before = df.truncate(after=current_idx).iloc[:-1]
    return before.index[-1] if 0 < len(before) else None

print(get_next_idx(df, cur_dt) or cur_dt)
print(get_prev_idx(df, cur_dt) or cur_dt)

相关问题