给定一个数据帧df
,我想根据前一行中的值为每一行生成一个新的变量/列。 df
已排序,以便行的顺序有意义。
通常情况下,我们可以使用map
或apply
,但似乎它们都不允许访问上一行中的值。
例如,给定现有行a b c
,我想生成一个新列d
,该列基于使用前一行c
值的某些计算。
我应该怎么做大熊猫?
答案 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-moments和http://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:我相当肯定这会使申请操作变慢,但我没有做任何测试来计算出多少。