如何在pandas中使用多个列Map函数?

osh3o9ms  于 11个月前  发布在  其他
关注(0)|答案(7)|浏览(142)

我已经检查了map、apply、mapapply和合并,但似乎找不到一种简单的方法来执行以下操作:
我有一个有10列的数组,我需要把其中的三列传递给一个接受标量并返回标量的函数。

some_func(int a, int b, int c) returns int d

字符串
我想应用这个方法,并使用结果在嵌套框架中创建一个新列。

df['d'] = some_func(a = df['a'], b = df['b'], c = df['c'])


我找到的所有解决方案似乎都建议重写some_func来处理Series而不是scalar,但这是不可能的,因为它是另一个包的一部分。

b4qexyjb

b4qexyjb1#

使用pd.DataFrame.apply(),如下所示:

df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']), axis=1)

字符串
注意事项:由于@ashishsingal询问列,axis参数应该提供值1,因为默认值为0(如documentation和下面复制的)。
轴:{0或“index”,1或“columns”},默认值为0

  • 0或“index”:将函数应用于每列
  • 或'columns':将函数应用于每一行
hzbexzde

hzbexzde2#

对于这样一个老问题,我发现将函数参数压缩成元组,然后将函数作为列表解析应用要比使用df.apply快得多。例如:

import pandas as pd

# Setup:
df = pd.DataFrame(np.random.rand(10000, 3), columns=list("abc"))
def some_func(a, b, c):
    return a*b*c

# Using apply:
%timeit df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']), axis=1)

字符串
222 ms ± 63.8 ms/循环(7次运行的平均值±标准差,每次1个循环)

# Using tuples + list comprehension:
%timeit df["d"] = [some_func(*a) for a in tuple(zip(df["a"], df["b"], df["c"]))]


8.07 ms ± 640 µs/循环(7次运行的平均值±标准差,每次100个循环)

6jygbczu

6jygbczu3#

我使用的map和列表理解一样快(比apply快得多):

df['d'] = list(map(some_func, df['a'], df['b'], df['c']))

字符串
在我的机器上:

import pandas as pd

# Setup:
df = pd.DataFrame(np.random.rand(10000, 3), columns=list("abc"))
def some_func(a, b, c):
    return a*b*c

# Using apply:
%timeit df['d'] = df.apply(lambda x: some_func(a = x['a'], 
b = x['b'], c = x['c']), axis=1)


130 ms ± 1.11 ms/循环(7次运行的平均值±标准差,每次10个循环)

%timeit df['d'] = list(map(some_func, df['a'], df['b'], df['c']))


3.91 ms ± 22.9 µs/循环(7次运行的平均值±标准差,每次100个循环)

nbnkbykc

nbnkbykc4#

我正在使用以下内容:

df['d'] = df.apply(lambda x: some_func(a = x['a'], b = x['b'], c = x['c']))

字符串
似乎工作得很好,但如果其他人有更好的解决方案,请让我知道。

vc9ivgsu

vc9ivgsu5#

非常好的使用列表理解的技巧,比如推荐的 Toby Petty

df["d"] = [some_func(*a) for a in tuple(zip(df["a"], df["b"], df["c"]))]

字符串
这可以通过移除元组示例化来进一步优化

df["d"] = [some_func(*a) for a in zip(df["a"], df["b"], df["c"])]


Map多个列的一种更快的方法是使用numpy中的frompyfunc创建python函数的矢量化版本

import numpy as np
    
some_func_vec = np.frompyfunc(some_func, 3, 1)
df["d"] = some_func_vec(df["a"], df["b"], df["c"])

pdtvr36n

pdtvr36n6#

如果它是一个非常简单的函数,比如一个基于简单算术的函数,那么它很有可能被向量化。例如,可以直接从列中进行线性组合:

df["d"] = w1*df["a"] + w2*df["b"] + w3*["c"]

字符串
其中w1、w2、w3是标量权重。

jchrr9hc

jchrr9hc7#

您还可以

df['d'] = df.agg(lambda row : some_function(row.a, row.b, row.c), axis=1)

字符串
我认为它比df.apply快得多。

相关问题