在迭代数据帧时是否有一种简单的方法可以引用上一行?
在以下数据框架中,我希望B列在A > 1
时更改为1,并且在A < -1
更改为-1时保持为1。
In [11]: df
Out[11]:
A B
2000-01-01 -0.182994 0
2000-01-02 1.290203 0
2000-01-03 0.245229 0
2000-01-08 -1.230742 0
2000-01-09 0.534939 0
2000-01-10 1.324027 0
这是我试过的,但显然你不能只从索引中减去1:
for idx,row in df.iterrows():
if df["A"][idx]<-1:
df["B"][idx] = -1
elif df["A"][idx]>1:
df["B"][idx] = 1
else:
df["B"][idx] = df["B"][idx-1]
我也试过使用get_loc
但是完全迷失了,我确定我错过了一个非常简单的解决方案!
答案 0 :(得分:1)
这是你想要做的事情?
In [38]: df = DataFrame(randn(10,2),columns=list('AB'))
In [39]: df['B'] = np.nan
In [40]: df.loc[df.A<-1,'B'] = -1
In [41]: df.loc[df.A>1,'B'] = 1
In [42]: df.ffill()
Out[42]:
A B
0 -1.186808 -1
1 -0.095587 -1
2 -1.921372 -1
3 -0.772836 -1
4 0.016883 -1
5 0.350778 -1
6 0.165055 -1
7 1.101561 1
8 -0.346786 1
9 -0.186263 1
答案 1 :(得分:0)
这里有类似的问题:Reference values in the previous row with map or apply。
我的印象是,大熊猫应该处理迭代,我们不应该自己做...因此,我选择使用DataFrame'apply'方法。
以上是我在上面链接的其他问题上发布的相同答案......
您可以使用数据框'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:我相当肯定这会使申请操作变慢,但我没有做任何测试来计算出多少。
答案 2 :(得分:0)
试试这个:如果第一个值既不是.c
,也不是>= 1
设置为< -1
或者您喜欢的任何内容。
0
这解决了所述问题,但引用前一行的真正解决方案是使用df["B"] = None
df["B"] = np.where(df['A'] >= 1, 1,df['B'])
df["B"] = np.where(df['A'] < -1, -1,df['B'])
df = df.ffill().fillna(0)
或.shift()