如何获取列中列表的最大值和最小值?

10

鉴于此,我有如下数据框:

import pandas as pd
import numpy as np

dict = {
        "A": [[1,2,3,4],[3],[2,8,4],[5,8]]
}

dt = pd.DataFrame(dict)

我希望获得B列每行的最大值最小值。我最喜欢的输出结果是:

              A    B
0  [1, 2, 3, 4]    [1,4]
1           [3]    [3,3] 
2     [2, 8, 4]    [2,8] 
3        [5, 8]    [5,8]

我已经尝试过以下代码,但它并没有起作用:

dt["B"] =[np.min(dt.A), np.max(dt.A)]

1
我的意思是,这个问题中需要像循环一样的东西: https://dev59.com/h2Qn5IYBdhLWcg3w5qlg 然而,apply 是一个好的解决方案。 - Jeff
4个回答

12

像这样:

In [1592]: dt['B'] = dt.A.apply(lambda x: [min(x), max(x)])     
In [1593]: dt                                   
Out[1593]: 
              A       B
0  [1, 2, 3, 4]  [1, 4]
1           [3]  [3, 3]
2     [2, 8, 4]  [2, 8]
3        [5, 8]  [5, 8]

正如 @Ch3steR 建议的那样,使用map因为它更快:

dt['B'] = dt.A.map(lambda x: [min(x), max(x)]) 

1
dt.A.map(...)pd.Series.apply 稍微快一点,因为 pd.Series.map 专门用于逐元素计算。虽然 map 快了大约 ~20-30µs,但差别不是很大。 - Ch3steR

10
你可以创建DataFrame,然后使用 DataFrame.agg 来计算最小值和最大值,转换为列表并重新赋值,如果不想使用循环(Apply 在底层是循环),可以这样做:
df = pd.DataFrame(dt.A.tolist())
dt['B'] = df.agg(['min','max'], axis=1).astype(int).values.tolist()
print (dt)
              A       B
0  [1, 2, 3, 4]  [1, 4]
1           [3]  [3, 3]
2     [2, 8, 4]  [2, 8]
3        [5, 8]  [5, 8]

如果循环没有问题,另一种解决方案是使用 list comprehension,它应该像 apply 一样更快,这取决于真实数据:

如果循环没有问题,另一种解决方案是使用 list comprehension,它应该像 apply 一样更快,这取决于真实数据:

dt['B'] =  [[min(x), max(x)] for x in dt.A]

2
在所有的解决方案中,[[min(x), max(x)] for x in dt.A] 是最快的。+1 - Ch3steR
@Ch3steR,它比jez的第一个解决方案更快吗?我没想到。 - Erfan
1
@Erfan 是的,我对所有解决方案都进行了 timeit 测试。而 list comp 比第二快的解决方案快了10倍。也许我的分析可能不公平,因为我没有使用大型列表和大型数据框进行测试。 - Ch3steR
1
啊好的,我认为应该在相当大的数据上进行比较,以看到方法的效率。 - Erfan
在第一种方法中,它并不是循环。它们都是矢量化的方法。这就是为什么我不认为它会比循环慢。实际上,我相当确定它会更快。 - Erfan
显示剩余2条评论

6

除了使用 explode 的方式外,还有一个替代方法:

dt['B'] = (dt['A'].explode().astype(int).groupby(level=0).agg(['min','max'])
           .to_numpy().tolist())
print(dt)

              A       B
0  [1, 2, 3, 4]  [1, 4]
1           [3]  [3, 3]
2     [2, 8, 4]  [2, 8]
3        [5, 8]  [5, 8]

4

在 dt.A 的排序值上使用列表推导式

 dt['B']= [[row[0], row[-1]] for row in dt.A.map(lambda x: sorted(x))]

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接