如何将自定义函数应用于pandas数据帧的每一行

时间:2017-11-18 16:01:53

标签: python pandas numpy dataframe

我有以下示例:

import pandas as pd
import numpy as np

df = pd.DataFrame([(0,2,5), (2,4,None),(7,-5,4), (1,None,None)])

def clean(series):
    start = np.min(list(series.index[pd.isnull(series)]))
    end = len(series)
    series[start:] = series[start-1]
    return series

我的目标是获取一个数据框,其中包含None值的每一行都填入最后一个可用的数值。

所以,例如,在数据帧的第3行运行此函数,我将生成以下内容:

row = df.ix[3]
test = clean(row)
test

0    1.0
1    1.0
2    1.0
Name: 3, dtype: float64

我无法使用.apply()方法工作,即df.apply(clean,axis = 1)

我应该提到这是一个玩具示例 - 我将在真实中编写的自定义函数在填充值时更具动态性 - 所以我不是在寻找像.ffill或.fillna这样的基本实用程序

3 个答案:

答案 0 :(得分:1)

apply方法不起作用,因为当行完全填满时,clean函数将不知道从哪里开始索引,因为给定系列的空数组。

因此在更改系列数据之前使用条件,即

def clean(series):
    # Creating a copy for the sake of safety 
    series = series.copy()
    # Alter series if only there exists a None value
    if pd.isnull(series).any():

        start = np.min(list(series.index[pd.isnull(series)]))

        # for completely filled row 
        # series.index[pd.isnull(series)] will return 
        # Int64Index([], dtype='int64')

        end = len(series)
        series[start:] = series[start-1]
    return series

df.apply(clean,1)

输出:

     0    1    2
0  0.0  2.0  5.0
1  2.0  4.0  4.0
2  7.0 -5.0  4.0
3  1.0  1.0  1.0

希望它澄清为什么申请不起作用。我还建议考虑使用builtins来清理数据,而不是从头开始编写函数。

答案 1 :(得分:0)

首先,这是解决玩具问题的代码。但是这段代码并不是你想要的。

df.ffill(axis=1)

接下来,我尝试测试您的代码。

df.apply(clean,axis=1)
#...start = np.min(list(series.index[pd.isnull(series)]))...
#=>ValueError: ('zero-size array to reduction operation minimum 
#                which has no identity', 'occurred at index 0')

要了解情况,请使用lambda函数进行测试。

df.apply(lambda series:list(series.index[pd.isnull(series)]),axis=1)
0        []
1       [2]
2        []
3    [1, 2]
dtype: object

下一个表达式会产生相同的值错误:

import numpy as np
np.min([])

总之,pandas.apply()运行良好,但清洁功能并不适用。

答案 2 :(得分:0)

你可以使用像填充物一样的回填物吗?我认为如果回填符合您的情况,这可能会更有效..

即。

df.fillna(method='backfill')

然而,假设细胞中存在np.nan?

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html