以下是代码:
import pandas as pd
import numpy as np
a = pd.Series(['1a', '2a'])
b = pd.Series(['1b', '2b'])
c = pd.Series([2, 3])
df = pd.concat((a.rename('a'), b.rename('b'), c.rename('c')), axis=1)
def ar(a, b, c):
arr = pd.DataFrame(np.diag(np.arange(c)))
arr['a'] = a
arr['b'] = b
return arr
如何使用apply方法生成:
a b 0 1 2 --------------------- 1a 1b 0 0 NaN 1a 1b 0 1 NaN 2a 2b 0 0 0 2a 2b 0 1 0 2a 2b 0 0 1
...像df.c.apply(ar, df.a, df.b)
这样的东西不起作用。
感谢
答案 0 :(得分:1)
一种快速而简单的方法是使用np.vectorize
“向量化”您的函数,允许numpy“隐藏”循环(很像apply
,但开销较少)。
v = np.vectorize(ar)
pd.concat(v(df.a, df.b, df.c))
0 1 a b 2
0 0 0 1a 1b NaN
1 0 1 1a 1b NaN
0 0 0 2a 2b 0.0
1 0 1 2a 2b 0.0
2 0 0 2a 2b 2.0
vectorize
作为输入,一个对标量进行操作的函数,并允许您传递按元素操作的向量。
这类似于循环输入的zip
ped版本并在每次迭代时调用ar
-
r = []
for x, y, z in zip(df.a, df.b, df.c):
r.append(ar(x, y, z))
pd.concat(r)
0 1 a b 2
0 0 0 1a 1b NaN
1 0 1 1a 1b NaN
0 0 0 2a 2b 0.0
1 0 1 2a 2b 0.0
2 0 0 2a 2b 2.0
答案 1 :(得分:1)
这里可以使用map
函数,这与数据框架的apply
非常相似:
outlist = list(map(lambda x,y,z: ar(x,y,z), a,b,c))
outdf = pd.concat(list(map(pd.DataFrame, outlist)))
# or: outdf = pd.concat([pd.DataFrame(out[0]), pd.DataFrame(out[1])])
print(outdf)
输出:
0 1 a b 2
0 0 0 1a 1b NaN
1 0 1 1a 1b NaN
0 0 0 2a 2b 0.0
1 0 1 2a 2b 0.0
2 0 0 2a 2b 2.0