假设我有一个df,它的列是" ID " " col_1 " " col_2 "我定义了一个函数:
F = x, y: my_function_expression。
现在我想应用f到df的两个列'col_1', 'col_2'来逐个元素计算一个新列'col_3',有点像:
df['col_3'] = df[['col_1','col_2']].apply(f)
# Pandas gives : TypeError: ('<lambda>() takes exactly 2 arguments (1 given)'
怎么办?
**添加详细示例如下***
import pandas as pd
df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]})
mylist = ['a','b','c','d','e','f']
def get_sublist(sta,end):
return mylist[sta:end+1]
#df['col_3'] = df[['col_1','col_2']].apply(get_sublist,axis=1)
# expect above to output df as below
ID col_1 col_2 col_3
0 1 0 1 ['a', 'b']
1 2 2 4 ['c', 'd', 'e']
2 3 3 5 ['d', 'e', 'f']
一个有趣的问题!我的回答如下:
import pandas as pd
def sublst(row):
return lst[row['J1']:row['J2']]
df = pd.DataFrame({'ID':['1','2','3'], 'J1': [0,2,3], 'J2':[1,4,5]})
print df
lst = ['a','b','c','d','e','f']
df['J3'] = df.apply(sublst,axis=1)
print df
输出:
ID J1 J2
0 1 0 1
1 2 2 4
2 3 3 5
ID J1 J2 J3
0 1 0 1 [a]
1 2 2 4 [c, d]
2 3 3 5 [d, e]
我将列名更改为ID,J1,J2,J3,以确保ID < J1 < J2 < J3,因此列以正确的顺序显示。
再简单说一下:
import pandas as pd
df = pd.DataFrame({'ID':['1','2','3'], 'J1': [0,2,3], 'J2':[1,4,5]})
print df
lst = ['a','b','c','d','e','f']
df['J3'] = df.apply(lambda row:lst[row['J1']:row['J2']],axis=1)
print df
我要投票支持np。vectorize。它允许你只拍摄x个列,而不处理函数中的数据帧,所以它非常适合你不控制的函数,或者做一些像发送2列和一个常数到一个函数(即col_1, col_2, 'foo')。
import numpy as np
import pandas as pd
df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]})
mylist = ['a','b','c','d','e','f']
def get_sublist(sta,end):
return mylist[sta:end+1]
#df['col_3'] = df[['col_1','col_2']].apply(get_sublist,axis=1)
# expect above to output df as below
df.loc[:,'col_3'] = np.vectorize(get_sublist, otypes=["O"]) (df['col_1'], df['col_2'])
df
ID col_1 col_2 col_3
0 1 0 1 [a, b]
1 2 2 4 [c, d, e]
2 3 3 5 [d, e, f]
我相信这不会像使用Pandas或Numpy操作的解决方案那么快,但如果你不想重写你的函数,你可以使用map。使用原始示例数据-
import pandas as pd
df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]})
mylist = ['a','b','c','d','e','f']
def get_sublist(sta,end):
return mylist[sta:end+1]
df['col_3'] = list(map(get_sublist,df['col_1'],df['col_2']))
#In Python 2 don't convert above to list
我们可以通过这种方式向函数传递任意数量的参数。输出就是我们想要的
ID col_1 col_2 col_3
0 1 0 1 [a, b]
1 2 2 4 [c, d, e]
2 3 3 5 [d, e, f]
我假设你不想改变get_subblist函数,而只是想使用DataFrame的apply方法来完成这项工作。为了得到你想要的结果,我写了两个帮助函数:get_sublist_list和unlist。正如函数名所示,首先获取子列表的列表,然后从该列表中提取子列表。最后,我们需要调用apply函数将这两个函数应用到df[['col_1','col_2']]数据帧。
import pandas as pd
df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]})
mylist = ['a','b','c','d','e','f']
def get_sublist(sta,end):
return mylist[sta:end+1]
def get_sublist_list(cols):
return [get_sublist(cols[0],cols[1])]
def unlist(list_of_lists):
return list_of_lists[0]
df['col_3'] = df[['col_1','col_2']].apply(get_sublist_list,axis=1).apply(unlist)
df
如果不使用[]将get_sublist_list函数括起来,则get_sublist_list函数将返回一个普通列表,它将引发ValueError: could not broadcast input array from shape(3)到shape(2),正如@Ted Petrou所提到的那样。