Pandas:Apply():返回多个值

3 投票
1 回答
1352 浏览
提问于 2025-04-18 04:45

我的数据是以年份为基础的,年份作为索引。我有一个叫做someFunc()的函数,它对分组后的数据进行一些操作。不过,这个函数会返回两个值(两个浮点数,而不是列)。我想把这两个值放到旧数据框中的两个新列里。为了演示,我想用一个简单的函数来说明:

def someFunc(group):
    a = 1
    b = 2
    return pd.DataFrame([[a, b]], columns={'colA', 'colB'}, index=[group['year'][0]])
results = df.groupby(level=0).apply(someFunc)
pd.merge(df, results, left_index=True, right_index=True)

但是,这样会产生一个双重索引的值:一个是因为我添加了索引,另一个是来自apply()的索引:

results
                colA        colB
year                            
1961 1961          1           2
1962 1962          1           2
1963 1963          1           2

因此,合并就无法正常工作。我尝试了其他各种方法(包括返回numpy数组),但都不太好用。我该怎么办呢?我知道我可以把这个函数拆分开,分别运行两次代码,针对每一列 - 但这样效率不高。为了更清楚,我期望的结果(对于变量result)是:

results
                colA        colB
year                            
1961               1           2
1962               1           2
1963               1           2

在此之前,数据看起来是这样的:

           c      a        b  
year                                                                          
1983     722   1001  1.06300  
1984     722   1001  1.24225   
1985     722   1001  2.78925   
1986     722   1001  0.59600   
1982  442110   1003  1.86300 

中间结果

return pd.DataFrame([[a, b]], columns=['colA', 'colB'], index=[group['year'].max()])

返回:

           colA       colB
1961         30   2.434379

所以这就是关键问题,对吧?它返回了一个带索引的东西,然后apply()又在上面叠加了自己的索引。由于没有办法返回一个没有索引的数据框,我猜解决方案应该在影响apply()上。

解决方案

正如在某个评论中提到的:

results = df.groupby(level=0).apply(someFunc).reset_index(level=0, drop=True)

1 个回答

1

这段代码在使用你的数据时对我有效。

In [57]:

temp="""year           c      a        b                                                                
1983     722   1001  1.06300  
1984     722   1001  1.24225   
1985     722   1001  2.78925   
1986     722   1001  0.59600   
1982  442110   1003  1.86300 """

df = pd.read_csv(io.StringIO(temp), sep='\s+')
df
Out[57]:
   year       c     a        b
0  1983     722  1001  1.06300
1  1984     722  1001  1.24225
2  1985     722  1001  2.78925
3  1986     722  1001  0.59600
4  1982  442110  1003  1.86300

[5 rows x 4 columns]
In [66]:

def someFunc(group):
    a = 1
    b = 2
    #print(group['year'].values)
    return pd.DataFrame([[a, b]], columns={'colA', 'colB'}, index=[group['year'].max()])
df.groupby(level=0).apply(someFunc)
Out[66]:
        colA  colB
0 1983     1     2
1 1984     1     2
2 1985     1     2
3 1986     1     2
4 1982     1     2

[5 rows x 2 columns]

编辑

经过进一步讨论,上面的代码也显示了你遇到的重复索引问题,所以你可以使用 reset_index 来消除重复。

In [91]:

def someFunc(group):
    a = 1
    b = 2
    return pd.DataFrame([[a, b]], columns={'colA', 'colB'}, index=[group['year'].max()])
df.groupby(level=0).apply(someFunc).reset_index(level=0, drop=True)

Out[91]:
      colA  colB
1983     1     2
1984     1     2
1985     1     2
1986     1     2
1982     1     2

[5 rows x 2 columns]

撰写回答