基于返回的lambda函数向pandas dataframe添加多行

2024-09-30 04:27:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个pandas数据帧,可以表示为:

myDF = pd.DataFrame({'value':[5,2,4,3,6,1,4,8]})
print(myDF)

   value
0      5
1      2
2      4
3      3
4      6
5      1
6      4
7      8

我可以添加一个新列,该列包含作用于“value”列内容的函数的返回值。例如,我可以添加一个名为“square”的列,该列包含值的平方,方法是定义一个函数,然后使用lambda,如下所示:

^{pr2}$

…生产

   value  square
0      5      25
1      2       4
2      4      16
3      3       9
4      6      36
5      1       1
6      4      16
7      8      64

(注意:我使用的实际函数比这个更复杂,但这个简单的平方过程可以用来说明。)

我的问题是,myFunc()函数能否返回一个元组(或者一个字典或一个列表),它可以用来在数据帧中添加多个新列?作为一个(非常简单的)例子,要为正方形、立方体、四次幂添加新列,是否可以做类似于:

def myFunc(x):
    mySquare = x*x
    myCube = x*x*x
    myFourth = x*x*x*x
    return mySquare,myCube,myFourth

myDF['square'],myDF['cubed'],myDF['fourth'] = myDF['value'].map(lambda x: myFunc(x))

…产生以下结果:

   value  square  cubed  fourth
0      5      25    125     625
1      2       4      8      16
2      4      16     64     256
3      3       9     27      81
4      6      36    216    1296
5      1       1      1       1
6      4      16     64     256
7      8      64    512    4096

编写3个单独的函数似乎是不必要的重复。到目前为止,我尝试过的所有变体都没有起作用(上面的失败是:ValueError:太多的值无法解包(预期为3))。在

如前所述,正方形、立方体和四次方幂的例子仅用于说明目的。我知道有更有效的方法来计算数据帧中的这些值。但是,我对基于单步执行列的每个单元格向数据帧添加多个列的方法感兴趣。在


Tags: 数据方法lambda函数valuemyfunc例子square
2条回答

您可以通过解压和重新打包myFunc()的结果来实现这一点(另请注意,如果已经有myFunc可用,则不需要lambda):

myDF['square'],myDF['cubed'],myDF['fourth'] = zip(*myDF['value'].map(myFunc))

使用zip(*arg)是交换元组集合方向的标准技巧。*将结果中的每一行转换为zip()函数的参数。然后zip()将每个参数的第一个元素组合到一个列表中(第一列),然后将第二个元素组合到另一个列表中,依此类推

或者,可以批量创建列,然后按元组分配:

^{pr2}$

通常,为了可读性,我会这样做:

myDF = pd.DataFrame(
    dict(
        value=myDF['value'],
        square=myDF['value'] ** 2,
        cube=myDF['value'] ** 3,
        fourth=myDF['value'] ** 4
    ),
    columns=['value', 'square', 'cube', 'fourth']  # set column order
)

但真的很难战胜这一点:

myDF['square'] = myDF['value'] ** 2
myDF['cube']   = myDF['value'] ** 3
myDF['fourth'] = myDF['value'] ** 4

这是一个“pythonic”解决方案,因为它简单、易读、易于调试和高效(也就是说,它很好地利用了pandas的内置功能)。在

您可以根据结果创建一个数据帧,然后将其连接到原始数据帧。然后需要重命名列。在

df = pd.concat([myDF, pd.DataFrame([myFunc(x) for x in myDF['value']])], axis=1)
df.columns = myDF.columns.tolist() + ['square', 'cubed', 'fourth']
>>> df
   value  square  cubed  fourth
0      5      25    125     625
1      2       4      8      16
2      4      16     64     256
3      3       9     27      81
4      6      36    216    1296
5      1       1      1       1
6      4      16     64     256
7      8      64    512    4096

相关问题 更多 >

    热门问题