按行数据帧分割

Row-wise DataFrame segmentation

给定以下数据框:

    df = pd.DataFrame(data={'item': [1, 2, 3, 4], 'start':[0.0, 2.0, 8.0, 6.0], 
                            'end': [2.0, 6.0, 8.0, 14.0]})

如何通过将区间 'start' - 'end' 分割成 2 的倍数来快速逐行扩展上述数据帧?

对于上面的例子,生成的数据帧应该是

    Out=
       item  start   end    
       1     0.0     2.0
       2     2.0     4.0
       2     4.0     6.0
       3     8.0     8.0
       4     6.0     8.0  
       4     8.0     10.0  
       4     10.0    12.0  
       4     12.0    14.0  

性能对我来说至关重要,因为我有数百万行要检查。 对于那些不需要分段的行,我已经使用布尔索引过滤了整个数据框。这是一个很大的加速但是,在其余的行上,我应用了 'for loop' 并制作了我一直附加的正确长度的数据帧。不幸的是,性能不足以处理数百万行。

期待高手解答!

您可以编写一个函数,该函数 return 是扩展开始和结束时间的 DataFrame。在这个例子中,我 groupby item 因为我不确定你是否可以 return 来自 apply 的 DataFrame 而不是先将它分组。

def convert(row):
    start = row.start.values[0]
    end = row.end.values[0]
    if start == end:
        return pd.DataFrame([[start, end]], columns=['start', 'end'])
    else:
        return pd.DataFrame({'start': np.arange(start, end, 2),
                            'end':np.arange(start + 2, end + 2, 2)},
                           columns=['start', 'end'])

df1=df.groupby('item').apply(convert)
df1.index = df1.index.droplevel(1)
df1.reset_index()

    item  start   end
0     1    0.0   2.0
1     2    2.0   4.0
2     2    4.0   6.0
3     3    8.0   8.0
4     4    6.0   8.0
5     4    8.0  10.0
6     4   10.0  12.0
7     4   12.0  14.0

从原始数据帧开始:

    import pandas as pd
    import numpy as np
    df = pd.DataFrame(data={'item': [1, 2, 3, 4], 'start':[0.0, 2.0, 8.0, 6.0], 
                            'end': [2.0, 6.0, 10.0, 14.0]})

然后,运行下面的代码:

    lengths = pd.Series([1, 2, 1, 4]) #  For the example, I just created this array, 
                                      #  but obviously I would use the mod function to 
                                      #  determine the number of segments to create

    # Row below elongates the dataframe according to the array 'lengths'

    df = df.reindex(np.repeat(df.index.values, lengths), method='ffill')
    df['start'] += pd.Series(df.groupby(level=0).cumcount()*2.0)
    df['end'] = df['start'] + 2.0
    print df

请注意,初始数据帧包含错误。项目“3”需要 'start=8.0' 和 'end=10.0'。

由于使用了 pandas Cython 函数,我相信这种方法非常快。当然,仍然对其他可能性持开放态度。