Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 应用带多个参数的函数创建新列_Python_Pandas - Fatal编程技术网

Python 应用带多个参数的函数创建新列

Python 应用带多个参数的函数创建新列,python,pandas,Python,Pandas,我想通过对两个现有列应用函数,在pandas数据框中创建一个新列。在此之后,当我只需要一列作为参数时,我就能够创建一个新列: import pandas as pd df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]}) def fx(x): return x * x print(df) df['newcolumn'] = df.A.apply(fx) print(df) 但是,当函数需要多个参数时,我不知道如何执行相同的操作

我想通过对两个现有列应用函数,在
pandas
数据框中创建一个新列。在此之后,当我只需要一列作为参数时,我就能够创建一个新列:

import pandas as pd
df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})

def fx(x):
    return x * x

print(df)
df['newcolumn'] = df.A.apply(fx)
print(df)
但是,当函数需要多个参数时,我不知道如何执行相同的操作。例如,如何通过将列a和列B传递给下面的函数来创建新列

def fxy(x, y):
    return x * y

这就解决了问题:

df['newcolumn'] = df.A * df.B
你也可以这样做:

def fab(row):
  return row['A'] * row['B']

df['newcolumn'] = df.apply(fab, axis=1)

如果可以重写函数,可以使用@greenAfrican示例。但如果不想重写函数,可以将其包装到apply中的匿名函数中,如下所示:

>>> def fxy(x, y):
...     return x * y

>>> df['newcolumn'] = df.apply(lambda x: fxy(x['A'], x['B']), axis=1)
>>> df
    A   B  newcolumn
0  10  20        200
1  20  30        600
2  30  10        300

或者,您可以使用numpy基础函数:

>>> import numpy as np
>>> df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})
>>> df['new_column'] = np.multiply(df['A'], df['B'])
>>> df
    A   B  new_column
0  10  20         200
1  20  30         600
2  30  10         300
def fab(row):                                                  
    return row['A'] * row['B'], row['A'] + row['B']
或在一般情况下矢量化任意函数:

>>> def fx(x, y):
...     return x*y
...
>>> df['new_column'] = np.vectorize(fx)(df['A'], df['B'])
>>> df
    A   B  new_column
0  10  20         200
1  20  30         600
2  30  10         300

还有一个dict风格的干净语法:

df["new_column"] = df.apply(lambda x: x["A"] * x["B"], axis = 1)
或者

如果需要同时创建多个列:

  • 创建数据帧:

    import pandas as pd
    df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})
    
  • 创建函数:

    >>> import numpy as np
    >>> df = pd.DataFrame({"A": [10,20,30], "B": [20, 30, 10]})
    >>> df['new_column'] = np.multiply(df['A'], df['B'])
    >>> df
        A   B  new_column
    0  10  20         200
    1  20  30         600
    2  30  10         300
    
    def fab(row):                                                  
        return row['A'] * row['B'], row['A'] + row['B']
    
  • 分配新列:

    df['newcolumn'], df['newcolumn2'] = zip(*df.apply(fab, axis=1))
    

  • 这个答案解决了这个玩具示例,足以让我重写我的实际函数,但它没有说明如何在不重写引用列的情况下应用先前定义的函数。请注意,向量化操作(第一个代码示例)比使用
    apply
    的代码示例具有更好的性能。感谢您的回答!我很好奇,这是最快的解决方案吗?使用
    np.vectorize()
    的矢量化版本速度惊人。谢谢。这是一个有用的解决方案。如果函数x和y的输入参数的大小不相等,则会出现错误。在这种情况下,@RomanPekar解决方案可以毫无问题地工作。我没有比较性能。我知道这是一个古老的答案,但是:我有一个边缘情况,在这种情况下,
    np.vectorize
    不起作用。原因是,其中一列的类型为
    pandas._libs.tslibs.timestamps.Timestamp
    ,通过矢量化将其转换为类型
    numpy.datetime64
    。这两种类型不可互换,导致功能表现不好。有什么建议吗?(除了
    。应用
    ,因为这显然是要避免的)伟大的解决方案!如果有人想知道vectorize对于字符串比较函数也能运行得很好,而且速度非常快。这是一个很好的技巧,它将列引用保留在apply调用附近(实际上是在其中)。我使用这个技巧和提供的多列输出技巧@toto_tico生成了一个3列输入,4列输出的函数!很好!哇,看来你是唯一一个不关注OP的简单示例,但解决了整个问题的人,谢谢,这正是我需要的!:)事实上,这应该是“官方”答案。我想知道如何用一个apply生成多个列!我用@Roman Pekar的答案生成了一个3列输入,4列输出的函数!很好!你能解释一下
    zip
    在这里做什么吗?谢谢
    zip
    同时迭代多个iterable(例如列表、迭代器)
    *df.apply
    将产生N(N=
    len(df)
    )个iterable,每个iterable包含2个元素
    zip
    将同时在N行上迭代,因此它将生成由N个元素组成的2个iterables。您可以对此进行测试,例如
    zip(['a','b'],['c','d'],['e','f'])
    将产生
    [('a','c','e'),('b','d','f')]
    (基本上是转置)。请注意,我有意使用单词
    yield
    ,而不是
    return
    ,因为我们谈论的是迭代器(因此,将zip结果转换为一个列表:
    list(zip(['a','b',['c','d',['e','f'])