Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.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 在df.apply()中的自定义函数中传递DataFrame中的不同列_Python_Pandas_Dataframe - Fatal编程技术网

Python 在df.apply()中的自定义函数中传递DataFrame中的不同列

Python 在df.apply()中的自定义函数中传递DataFrame中的不同列,python,pandas,dataframe,Python,Pandas,Dataframe,假设我有一个数据帧df: x y z 0 1 2 3 1 4 5 6 2 7 8 9 df['xz'] = df.apply(func, axis=1) 我想有两个新列,分别是x*y和x*z: x y z xy xz 0 1 2 3 2 3 1 4 5 6 20 24 2 7 8 9 56 63 因此,我定义了一个函数func(仅举个例子),它将字符串'y'或字符串'z'作为参数,以指示要与列x相乘的列: def func(row, colName): return r

假设我有一个数据帧
df

  x y z
0 1 2 3
1 4 5 6
2 7 8 9
df['xz'] = df.apply(func, axis=1)
我想有两个新列,分别是x*y和x*z:

  x y z xy xz
0 1 2 3  2  3
1 4 5 6 20 24
2 7 8 9 56 63
因此,我定义了一个函数
func
(仅举个例子),它将字符串
'y'
或字符串
'z'
作为参数,以指示要与列x相乘的列:

def func(row, colName):
    return row['x'] * row[colName]
并将该函数应用于数据帧
df

  x y z
0 1 2 3
1 4 5 6
2 7 8 9
df['xz'] = df.apply(func, axis=1)
显然,这里是错误的,因为我没有指定
colName
'y'
'z'
。问题是,
df.apply()

df['xz'] = df.apply(lambda x: func(x['x'], x[colName]), axis=1)
你的职能是:

def func(x, colName):
    return x * colName

您可以将lambda函数用于指定列,但也需要更改
func

def func(row, colName):
    return row * colName

cols = ['y', 'z']
for c in cols:
    df['x' + c] = df.apply(lambda x: func(x['x'], x[c]), axis=1)
def func(row, colName):
    return row['x'] * row[colName]

cols = ['y', 'z']
for c in cols:
    df['x' + c] = df.apply(lambda x: func(x, c), axis=1)
如果无法更改
func

def func(row, colName):
    return row * colName

cols = ['y', 'z']
for c in cols:
    df['x' + c] = df.apply(lambda x: func(x['x'], x[c]), axis=1)
def func(row, colName):
    return row['x'] * row[colName]

cols = ['y', 'z']
for c in cols:
    df['x' + c] = df.apply(lambda x: func(x, c), axis=1)


您可以在听写理解中使用
赋值
来完成此操作

选项1
保持第一列固定:

def func(row, j):
    return row['x'] * row[j]

cols = ['y', 'z']
df.assign(**{'x' + c : df.apply(func, args=c, axis=1) for c in cols})

   x  y  z  xy  xz
0  1  2  3   2   3
1  4  5  6  20  24
2  7  8  9  56  63

选项2
两列都不固定的备选方案:

def func(row, i, j):
    return row[i] * row[j]

pairs = [('x', 'y'), ('x', 'z')]
df.assign(**{''.join(p) : df.apply(func, args=p, axis=1) for p in pairs})

   x  y  z  xy  xz
0  1  2  3   2   3
1  4  5  6  20  24
2  7  8  9  56  63

pandas 0.22.0
中,我能够执行以下操作以获得您的预期输出:

df['xy'] = df.apply(func, axis=1, args='y')
df['xz'] = df.apply(func, axis=1, args='z')
pd.DataFrame.apply的docstring显示以下内容:

pd.DataFrame.apply(self, func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
.
.
.
args : tuple; Positional arguments to pass to function in addition to the array/series

因此,您需要使用
df.apply()

中的
args
关键字参数将任何位置参数传递给
func
,我认为
eval
在这里是完美的

df['x*y'],df['x*z']=df.eval('x*y'),df.eval('x*z')
df
Out[14]: 
   x  y  z  x*y  x*z
0  1  2  3    2    3
1  4  5  6   20   24
2  7  8  9   56   63

我更喜欢第一个选项,但不太明白什么是
'x'+c
。新列的名称是?@PacmanKX,确切地说,在那里命名列。这只是简单的字符串连接。这真的很有效!只有一个小问题,
'x'+c
是列名吗?认为字符串可以用作列名。@PacmanKX-确切地说,它是列表理解,对于每个循环,都从
cols
list返回值。所以在第一个循环中
y
和第二个循环中
z
他,很好:)很酷!谢谢真不错。如果这是OP的真实用例,它将最适合。伟大的解决方案!谢谢你的回答!没有更改原始的
func
?我没有更改原始的
func
定义。如果我的答案或其他答案有用,请不要忘记-单击答案旁边的复选标记(
v
),将其从灰显切换为填充。接受的答案应该只有一个。