如何在熊猫中获得范围的开始和结束

时间:2014-04-02 07:14:47

标签: python pandas grouping

我有一个包含数字和数组的熊猫系列,我希望得到每组的开始和结束。以下代码执行此操作:

def get_ranges(d):
    results = []
    start = None
    for i in range(len(d) - 1):
        if start is None and not np.isnan(d.ix[i]):
            start = d.index[i]
        if start is not None and np.isnan(d.ix[i + 1]):
            results.append((start, d.index[i]))
            start = None
    if start is not None:
        results.append((start, d.index[i]))
    return pd.DataFrame(results, columns=['start', 'end'])

E.g:

In [24]: d = pd.Series([0, 1, 4, 2, nan, nan, nan, 4, 2, nan, 10, nan])

In[25]: get_ranges(d)
Out[25]: 
   start  end
0      0    3
1      7    8
2     10   10

[3 rows x 2 columns]

但似乎这是大熊猫应该能够轻松完成的事情,可能使用groupby。是否有一些内置的方法可以让我失去这些群体?

2 个答案:

答案 0 :(得分:1)

不确定是否有更方便的方法,以下是我正在使用的:

获取那些有数字但不是nan

的索引
In [134]: s = d.dropna().index.to_series()

In [135]: s
Out[135]: 
0      0
1      1
2      2
3      3
7      7
8      8
10    10
dtype: int64

开始和结束
In [136]: start = s[s.diff(1) != 1].reset_index(drop=True)

In [137]: end = s[s.diff(-1) != -1].reset_index(drop=True)

然后你可以通过

构建你想要的东西
In [138]: pd.DataFrame({'start': start, 'end': end}, columns=['start', 'end'])
Out[138]: 
   start  end
0      0    3
1      7    8
2     10   10

[3 rows x 2 columns]

答案 1 :(得分:1)

您可以使用isnull()cumsum()创建groupby键:

import pandas as pd
import numpy as np

nan = np.nan
d = pd.Series([0, 1, 4, 2, nan, nan, nan, 4, 2, nan, 10, nan])

mask = d.isnull()
index = mask.cumsum()
mask = ~mask

d[mask].groupby(index[mask]).agg(
{"start":lambda s:s.index[0],
 "end":lambda s:s.index[-1]}).reset_index(drop=True)

输出:

   start  end
0      0    3
1      7    8
2     10   10