Python Pandas Groupby聚合返回自定义输出(非一行)

Python Pandas Groupby聚合返回自定义输出(非一行),python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有一个以下格式的数据帧 | col1 | col2 | | 1 | day1 | | 1 | day2 | | 1 | day3 | | 2 | day1 | | 2 | day3 | 我有一个非常定制的逻辑/函数,它在一个数据帧上为col1的一个值工作,我希望应用于所有值。这有点像群比。然而,我似乎没有正确地得到聚合部分,因为在我看来,它似乎只返回1个值(比如max/min/count/)。如果我的聚合函数返回一个dataframe并且有超过

我有一个以下格式的数据帧

| col1 | col2  | 
|  1   |  day1 |
|  1   |  day2 |
|  1   |  day3 |
|  2   |  day1 | 
|  2   |  day3 | 
我有一个非常定制的逻辑/函数,它在一个数据帧上为col1的一个值工作,我希望应用于所有值。这有点像群比。然而,我似乎没有正确地得到聚合部分,因为在我看来,它似乎只返回1个值(比如max/min/count/)。如果我的聚合函数返回一个dataframe并且有超过1行呢

例如,预期的输出可以是

| col1 | col2       | 
|  1   |  day1-day2 |
|  1   |  day2-day3 |
|  2   |  day1-day3 |
正如您所知,有两行是从group1生成的,一行是从group2生成的。聚合逻辑是每两个连续行串联一次,甚至更复杂。这有点像Spark/Hadoop中的map-reduce思想,但无法在小组中运行。聚合

更新:

人们通常使用groupby().agg(sum),它作为sum返回1行或1个数字。但是,我有一个函数,它返回的数据帧可以是0、1或多行,它确实减少了行数,但还没有像groupby().agg(func)那样折叠为1行,在groupby.agg中可以这样做吗

def func(xdf):
    res = []
    for i in range(len(xdf)-1):
        res.append(xdf.iloc[i] + '-' + xdf.iloc[i+1])
    return pd.DataFrame(res) # return a dataframe, not a number, not a row.

我想这会让你到达你想要的地方

数据:

按每列分组

gb = df.groupby(['col1', 'col2']).nth(0)
然后又是groupby和dropna's

gb.groupby(['col1']).shift(-1).dropna()
产生

col1    col2    col3
1     day1    day2 
1     day2    day3 
2     day1    day3 

您可以使用
groupby.apply
,而不是使用
groupby.agg
,像这样使用数据和函数
func
,您可以

print (df.groupby('col1').apply(func))
             col2
col1             
1    0  day1-day2
     1  day2-day3
2    0  day1-day3
为了获得预期的输出格式,还可以使用
reset\u index

print (df.groupby('col1').apply(func)
         .reset_index(level=0)
         .reset_index(drop=True))
   col1       col2
0     1  day1-day2
1     1  day2-day3
2     2  day1-day3

​但在您的实际情况中,您可能不需要它

在distributed tech Spark v/s a 1核心技术(如pandas)中有不同的方法来实现这一点。pandas needs
rolling
可能基于pyspark的
join
输出,这完全取决于所涉及的分区,因此我们需要一个更清晰的示例来说明您在这里尝试执行的操作:)友好的建议是尽可能缩小到最相关的mcve。@anky,我已经提供了示例输入,sampleout,您认为还有什么可以帮助澄清的(它被标记为熊猫问题)@B.Mr.W。如果通过
apply
更改
agg
,它将按预期工作。试试df.groupby('col1')['col2'])。apply(func):)你只需要一些化妆品就可以让它看起来像你想要的want@Ben.T啊!!申请正是我在寻找的,如果你想发布一个样本答案,我会接受。谢谢Ben。同意@Ben.T apply在这里会很有用,这是一个很好的发现。这个问题更像是一个如何在一个组中返回多行的问题,我用了一个例子来说明这个想法,你的移位(-1)确实很好,但不是我想要的。那么多行是指像groupby和.nth([0,1])?为了说明这个想法,我对我的问题做了一些改进,func可以是任何定制的函数,坦率地说,结果可以是任何自由形式的数据帧。
print (df.groupby('col1').apply(func)
         .reset_index(level=0)
         .reset_index(drop=True))
   col1       col2
0     1  day1-day2
1     1  day2-day3
2     2  day1-day3