如何将pandas方法作为参数传递?

时间:2019-01-18 11:18:32

标签: python pandas parameter-passing

我有一个计算熊猫数据框的列模式的函数:

def my_func(df):
    for col in df.columns:
        stat = df[col].mode()
        print(stat)

但是我想使其更通用,以便我可以更改计算的统计量,例如意思是,最大值,...我试图将方法mode()作为参数传递给函数:

def my_func(df, pandas_stat):
    for col in df.columns:
        stat = df[col].pandas_stat()
        print(stat)

已引用:How do I pass a method as a parameter in Python

但是,这似乎不适用于我。 用一个简单的例子:

> A
     a    b
0  1.0  2.0
1  2.0  4.0
2  2.0  6.0
3  3.0  NaN
4  NaN  4.0
5  3.0  NaN
6  2.0  6.0
7  4.0  6.0

它无法识别命令模式:

> my_func(A, mode)
Traceback (most recent call last):

  File "<ipython-input-332-c137de83a530>", line 1, in <module>
    my_func(A, mode)

NameError: name 'mode' is not defined

所以我尝试了pd.DataFrame.mode:

> my_func(A, pd.DataFrame.mode)
Traceback (most recent call last):

  File "<ipython-input-334-dd913410abd0>", line 1, in <module>
    my_func(A, pd.DataFrame.mode)

  File "<ipython-input-329-8acf337bce92>", line 3, in my_func
    stat = df[col].pandas_stat()

  File "/anaconda3/envs/py36/lib/python3.6/site-packages/pandas/core/generic.py", line 4376, in __getattr__
    return object.__getattribute__(self, name)

AttributeError: 'Series' object has no attribute 'pandas_stat'

是否可以通过模式功能?

2 个答案:

答案 0 :(得分:1)

您可以使用内置的[getattr][1]__name__属性,但是我想这会使您的代码不清楚。可能存在更好的方法。

df = pd.DataFrame({'col1': list(range(5)), 'col2': list(range(5, 0, -1))})
df
Out:
   col1  col2
0     0     5
1     1     4
2     2     3
3     3     2
4     4     1

以这种方式定义my_func并将其应用于df

def my_func(df, pandas_stat):
    for col in df.columns:
        stat = getattr(df[col], pandas_stat.__name__)()
        print(stat)

my_func(df, pd.DataFrame.mean)
Out
2.0
3.0

说明:pd.DataFrame.mean具有属性__name__,其值为'mean'。与您可以调用相比,Getattr可以从pd.DataFrame对象获取此属性。

如果需要,您甚至可以传递参数:

def my_func(df, pandas_stat, *args, **kwargs):
    for col in df.columns:
        stat = getattr(df[col], pandas_stat.__name__)(*args, **kwargs)
        print(stat)

my_func(df, pd.DataFrame.apply, lambda x: x ** 2)
Out: 
0     0
1     1
2     4
3     9
4    16
Name: col1, dtype: int64
0    25
1    16
2     9
3     4
4     1
Name: col2, dtype: int64

但是我再说一遍,我想这种方法有点令人困惑。

修改
关于错误:

> my_func(A, pd.DataFrame.mode)
Traceback (most recent call last):

  File "<ipython-input-334-dd913410abd0>", line 1, in <module>
    my_func(A, pd.DataFrame.mode)

  File "<ipython-input-329-8acf337bce92>", line 3, in my_func
    stat = df[col].pandas_stat()

  File "/anaconda3/envs/py36/lib/python3.6/site-packages/pandas/core/generic.py", line 4376, in __getattr__
    return object.__getattribute__(self, name)

AttributeError: 'Series' object has no attribute 'pandas_stat'

执行df[col].pandas_stat()时,点.运算符将调用数据框对象的__getattribute__方法。它是getattr的类似物,但是它会自动将self作为第一个参数。
因此,第二个是方法的“名称”,在您的代码中为'pandas_stat'。由于pandas数据框没有具有此类名称的属性,因此它会破坏执行。

如果您为getattr提供了实际方法的正确名称(“ mean”,“ apply”等),则此函数会在列出所有方法的pd.DataFrame.__dict__中找到该方法,然后返回它。因此,您可以通过(*args, **kwargs)语法来调用它。

答案 1 :(得分:1)

您可以使用@extends('layout.layout') @section('content') <h1>{{ $titlePage }}</h1> @endsection 进行此操作:

getattr