python-调用函数

python-调用函数,python,function,pandas,dataframe,Python,Function,Pandas,Dataframe,在我下面的Python代码中,为什么不能用第二种方法调用函数?如果我想更改代码,以便使用第二种方法调用函数,我应该如何更改函数 import numpy as np import pandas as pd sales = {'Feb': [200, None, None],'Mar': [140, 215, 95]} df = pd.DataFrame.from_dict(sales) def impute_age(cols): Age = cols[0] Pclass = c

在我下面的Python代码中,为什么不能用第二种方法调用函数?如果我想更改代码,以便使用第二种方法调用函数,我应该如何更改函数

import numpy as np
import pandas as pd
sales = {'Feb': [200, None, None],'Mar': [140, 215, 95]}
df = pd.DataFrame.from_dict(sales)

def impute_age(cols):
    Age = cols[0]
    Pclass = cols[1]

    if pd.isnull(Age):
        if Pclass == 215:
            return 37
        elif Pclass == 2:
            return 29
        else:
            return 24
    else:
        return Age


#method 1
df['z'] = df[['Feb','Mar']].apply(impute_age, axis=1)

print(df)
#method 2
df['zz'] = impute_age(df[['Feb','Mar']])

巴拉斯·谢蒂下面的评论对我很有帮助。该函数期望at数组作为输入,而不是数据帧。无法使用df[0]访问数据帧的列…这会产生如下错误

df[0]
Traceback (most recent call last):

  File "<ipython-input-9-9ae93f22b889>", line 1, in <module>
    df[0]

  File "C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site-packages\pandas\core\frame.py", line 2062, in __getitem__
    return self._getitem_column(key)

  File "C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site-packages\pandas\core\frame.py", line 2069, in _getitem_column
    return self._get_item_cache(key)

  File "C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site-packages\pandas\core\generic.py", line 1534, in _get_item_cache
    values = self._data.get(item)

  File "C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site-packages\pandas\core\internals.py", line 3590, in get
    loc = self.items.get_loc(item)

  File "C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site-packages\pandas\core\indexes\base.py", line 2395, in get_loc
    return self._engine.get_loc(self._maybe_cast_indexer(key))

  File "pandas\_libs\index.pyx", line 132, in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:5239)

  File "pandas\_libs\index.pyx", line 154, in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:5085)

  File "pandas\_libs\hashtable_class_helper.pxi", line 1207, in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20405)

  File "pandas\_libs\hashtable_class_helper.pxi", line 1215, in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20359)

KeyError: 0
df[0]
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
df[0]
文件“C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site packages\pandas\core\frame.py”,第2062行,在u getitem中__
返回self.\u getitem\u列(键)
文件“C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site packages\pandas\core\frame.py”,第2069行,在_getitem_列中
返回self.\u获取\u项目\u缓存(密钥)
文件“C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site packages\pandas\core\generic.py”,第1534行,在获取项目缓存中
values=self.\u data.get(项目)
文件“C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site packages\pandas\core\internals.py”,第3590行,在get中
loc=自身项目。获取loc(项目)
文件“C:\Users\nikhi\AppData\Local\conda\conda\envs\tensorflowspyder\lib\site packages\pandas\core\index\base.py”,第2395行,位于get\U loc中
返回self.\u引擎。获取\u loc(self.\u可能\u cast\u索引器(键))
pandas.\u libs.index.IndexEngine.get\u loc(pandas\\u libs\index.c:5239)中第132行的文件“pandas\\u libs\index.pyx”
文件“pandas\\ libs\index.pyx”,第154行,在pandas.\ libs.index.IndexEngine.get\u loc中(pandas\\ libs\index.c:5085)
pandas.\u libs.hashtable.PyObjectHashTable.get_项中的文件“pandas\\u libs\hashtable\u class\u helper.pxi”,第1207行(pandas\\u libs\hashtable.c:20405)
pandas.\u libs.hashtable.PyObjectHashTable.get_项(pandas\\u libs\hashtable.c:20359)中第1215行的文件“pandas\\u libs\hashtable\u class\u helper.pxi”
关键错误:0

跨列应用函数与将数据帧传递给该函数不同<代码>应用是一个简化的for循环。它将每一行一次发送给函数,以收集数据,然后返回一个序列

要使第二种方法起作用,请在函数内部使用
iterrows
,并借助空列表收集数据,即

def impute_age2(cols):
    k = []
    for _,i in cols.iterrows():
        Age = i[0]
        Pclass = i[1]
        if pd.isnull(Age):
            if Pclass == 215:
                k.append(37)
            elif Pclass == 2:
                k.append(29)
            else:
                k.append(24)
        else:
            k.append(Age)
    return k

df['zz'] = impute_age(df[['Feb','Mar']])
输出:

Feb Mar zz 0 200.0 140 200.0 1 NaN 215 37.0 2 NaN 95 24.0 二月至三月 0 200.0 140 200.0 1.37.0 2 NaN 95 24.0
第一种方法的性能要高得多。我想知道你为什么要叫第二条路。愚蠢的问题。在第一个方法中使用
apply
一次传递一个项目,在第二个方法中传递整个列。如果要传递整列,
cols[0]
等于什么。您的问题的答案是使用方法1,我不会传递整列
df[['Feb','Mar']]
是一个数据帧…我知道方法1更好。我想知道为什么方法2不起作用如果
apply
一次发送一行,那么为什么我不能使用
df['zz']=impute_age(df['Feb','Mar']].head(1))
这是因为您发送数据帧作为函数的参数,而它不是一个借助索引访问的列表或序列。如果你说col[0],它将在df中搜索名为
0
的列。如果你想得到第一个值,然后将参数作为列表或数组传递,即
impute_age2(df[['Feb','Mar']]].head(1)。值[0]
。要得到所有值,当然是for循环。 Feb Mar zz 0 200.0 140 200.0 1 NaN 215 37.0 2 NaN 95 24.0