【问题标题】:Get two return values from Pandas apply从 Pandas apply 获取两个返回值
【发布时间】:2017-09-09 21:49:55
【问题描述】:

我正在尝试从 apply 方法返回两个不同的值,但我不知道如何获得所需的结果。

具有如下功能:

def fun(row):
    s = [sum(row[i:i+2]) for i in range (len(row) -1)]
    ps = s.index(max(s))
    return max(s),ps

df 为:

    6:00    6:15    6:30    
0   3       8       9       
1   60      62      116     

我正在尝试返回该行的最大值,但我还需要获取产生最大组合的第一个值的索引。

df["phour"] = t.apply(fun, axis=1)

我可以获得所需的输出,但我不知道如何在新列中获取索引。到目前为止,我在 tuple 中得到了两个答案

    6:00    6:15    6:30    phour
0   3       8       9       (17, 1)
1   60      62      116     (178, 1)

如何在自己的列中获取索引值?

【问题讨论】:

标签: python pandas


【解决方案1】:

如果您只是想获取最大值和 argmax,我建议使用 pandas API:

DataFrame.idxmax

所以:

df = pd.DataFrame({'A':[1,2,3,4], 'B':[2,3,4,1], 'C':[3,2,4,1]})
df

    A   B   C
0   1   2   3
1   2   3   2
2   3   4   4
3   4   1   1

df['Max'] = df.max(axis=1)
df['ArgMax'] = df.idxmax(axis=1)
df    

    A   B   C   Max ArgMax
0   1   2   3   3   C
1   2   3   2   3   B
2   3   4   4   4   B
3   4   1   1   4   A

更新
而如果需要实际的索引值,可以使用numpy.ndarray.argmax

df['ArgMaxNum'] = df[['A','B','C']].values.argmax(axis=1)


    A   B   C   Max ArgMax  ArgMaxNum
0   1   2   3   3   C   2
1   2   3   2   3   B   1
2   3   4   4   4   B   1
3   4   1   1   4   A   0

【讨论】:

  • 我需要获取每行连续值的最大值。以第一行为例,我需要在 11 到 17 之间进行选择,并知道最大序列中的索引从哪里开始
  • 啊,我明白了。我将添加另一个答案。
【解决方案2】:

一定有更好的方法,但你可以这样做:

df.merge(pd.DataFrame(((i,j) for 
                       i,j in df.apply(lambda x: fun(x)).values),
                      columns=['phour','index']),
         left_index=True,right_index=True)

【讨论】:

  • 感谢您的回答,这也有效,但老实说,我无法准确理解代码发生了什么。我可以更好地关注@Gordon Bean。
【解决方案3】:

将元组拆分为单独列的一种方法是元组解包:

df = pd.DataFrame({'A':[1,2,3,4], 'B':[2,3,4,1], 'C':[3,2,4,1], 'Double': [(1,2), (3,4), (5,6), (7,8)]})
df


    A   B   C   Double
0   1   2   3   (1, 2)
1   2   3   2   (3, 4)
2   3   4   4   (5, 6)
3   4   1   1   (7, 8)

df['D1'] = [d[0] for d in df.Double]
df['D2'] = [d[1] for d in df.Double]
df


    A   B   C   Double  D1  D2
0   1   2   3   (1, 2)  1   2
1   2   3   2   (3, 4)  3   4
2   3   4   4   (5, 6)  5   6
3   4   1   1   (7, 8)  7   8

【讨论】:

  • 感谢这项工作。这可能不是最好的和更推荐的方法,但它足以满足我的需要。
【解决方案4】:

你可以applypd.Series

df.drop('Double', 1).join(df.Double.apply(pd.Series, index=['D1', 'D2']))

   A  B  C  D1  D2
0  1  2  3   1   2
1  2  3  2   3   4
2  3  4  4   5   6
3  4  1  1   7   8

等价

df.drop('Double', 1).join(
    pd.DataFrame(np.array(df.Double.values.tolist()), columns=['D1', 'D2'])
)

设置
使用@GordonBean 的df

df = pd.DataFrame({'A':[1,2,3,4], 'B':[2,3,4,1], 'C':[3,2,4,1], 'Double': [(1,2), (3,4), (5,6), (7,8)]})

【讨论】:

  • 在回答这个问题之前我应该​​先看看四周:stackoverflow.com/questions/10751127/… :)
  • 这样干净多了。谢谢@piRSquared。
  • 非常好!但我们可以尝试让它变得更好:df.join(df.pop('Double').apply(pd.Series, index=['D1', 'D2'])) ;-)
【解决方案5】:

您可以像这样在单独的列中获取索引:

df[['phour','index']] = df.apply(lambda row: pd.Series(list(fun(row))), axis=1)

或者如果你稍微修改一下 fun:

def fun(row):
    s = [sum(row[i:i+2]) for i in range (len(row) -1)]
    ps = s.index(max(s))
    return [max(s),ps]

然后代码变得不那么复杂了:

 df[['phour','index']] = df.apply(lambda row: pd.Series(fun(row)), axis=1)

【讨论】:

    猜你喜欢
    • 2014-06-28
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 2017-04-19
    • 1970-01-01
    相关资源
    最近更新 更多