使用map或apply在上一行中引用值

时间:2014-04-28 06:15:59

标签: python pandas

给定一个数据帧df,我想根据前一行中的值为每一行生成一个新的变量/列。 df已排序,以便行的顺序有意义。

通常情况下,我们可以使用mapapply,但似乎它们都不允许访问上一行中的值。

例如,给定现有行a b c,我想生成一个新列d,该列基于使用前一行c值的某些计算。

我应该怎么做大熊猫?

2 个答案:

答案 0 :(得分:3)

如果您只想根据前一行进行计算,可以计算然后转移:

In [2]: df = pd.DataFrame({'a':[0,1,2], 'b':[0,10,20]})

In [3]: df
Out[3]:
   a   b
0  0   0
1  1  10
2  2  20

# a calculation based on other column
In [4]: df['c'] = df['b'] + 1

# shift the column
In [5]: df['c'] = df['c'].shift()

In [6]: df
Out[6]:
   a   b   c
0  0   0 NaN
1  1  10   1
2  2  20  11

如果您想根据多行进行计算,可以查看rolling_apply函数(http://pandas.pydata.org/pandas-docs/stable/computation.html#moving-rolling-statistics-momentshttp://pandas.pydata.org/pandas-docs/stable/generated/pandas.rolling_apply.html#pandas.rolling_apply

答案 1 :(得分:1)

您可以使用数据框'apply'功能,并利用未使用的'kwargs'参数存储上一行。

import pandas as pd

df = pd.DataFrame({'a':[0,1,2], 'b':[0,10,20]})

new_col = 'c'

def apply_func_decorator(func):
    prev_row = {}
    def wrapper(curr_row, **kwargs):
        val = func(curr_row, prev_row)
        prev_row.update(curr_row)
        prev_row[new_col] = val
        return val
    return wrapper

@apply_func_decorator
def running_total(curr_row, prev_row):
    return curr_row['a'] + curr_row['b'] + prev_row.get('c', 0)

df[new_col] = df.apply(running_total, axis=1)

print(df)
# Output will be:
#    a   b   c
# 0  0   0   0
# 1  1  10  11
# 2  2  20  33

此示例使用装饰器将前一行存储在字典中,然后在Pandas在下一行调用它时将其传递给该函数。

免责声明1:'prev_row'变量在第一行开始为空,因此在apply函数中使用它时,我必须提供一个默认值以避免'KeyError'。

免责声明2:我相当肯定这会使申请操作变慢,但我没有做任何测试来计算出多少。