熊猫根据日期组合行

fly*_*all 3 python pandas

我有一个客户数据框,其中包含他们收到的货件记录.不幸的是,这些可能重叠.我正在尝试减少行数,以便我可以看到连续使用的日期.有没有什么方法可以做到这一点除了蛮力iterrows实施?

这是一个示例和我想做的事情:

df = pd.DataFrame([['A','2011-02-07','2011-02-22',1],['A','2011-02-14','2011-03-10',2],['A','2011-03-07','2011-03-15',3],['A','2011-03-18','2011-03-25',4]], columns = ['Cust','startDate','endDate','shipNo'])
df
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

condensedDf = df.groupby(['Cust']).apply(reductionFunction)
condensedDF
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

reductionFunction将前3个记录分组为一个,因为在每种情况下,下一个的开始日期都在前一个结束日期之前.我基本上把多个记录重叠成一条记录.

关于良好"pythonic"实施的想法?我可以在每个小组内做一个讨厌的循环,但我不想......

jak*_*vdp 6

从根本上说,我认为这是一个图形连接问题:解决它的一种快速方法将是某种图形连接算法.熊猫不包括这样的工具,但scipy确实如此.您可以使用csgraphscipy中的压缩稀疏图()子模块来解决您的问题,如下所示:

from scipy.sparse.csgraph import connected_components

# convert to datetime, so min() and max() work
df.startDate = pd.to_datetime(df.startDate)
df.endDate = pd.to_datetime(df.endDate)

def reductionFunction(data):
    # create a 2D graph of connectivity between date ranges
    start = data.startDate.values
    end = data.endDate.values
    graph = (start <= end[:, None]) & (end >= start[:, None])

    # find connected components in this graph
    n_components, indices = connected_components(graph)

    # group the results by these connected components
    return data.groupby(indices).aggregate({'startDate': 'min',
                                            'endDate': 'max',
                                            'shipNo': 'first'})

df.groupby(['Cust']).apply(reductionFunction).reset_index('Cust')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果你想shipNo从这里做一些不同的事情,它应该非常简单.

请注意,connected_components()上面的函数不是暴力,而是使用快速算法来查找连接.