![](/img/trans.png)
[英]How to iterate over previous rows to compare values in a Pandas DataFrame
[英]How to iterate over a pandas dataframe while referencing previous rows?
我正在遍历一个Python数据框,发现它非常慢。 我了解在Pandas中您尝试对所有内容进行矢量化,但是在这种情况下,我特别需要进行迭代(或者如果可以进行矢量化,则不清楚如何执行此操作)。
逻辑很简单:您有两个列“ A”和“ B”,以及一个结果列“ signal”。 如果A等于1,则将signal设置为1。如果B等于1,则将signal设置为0。否则,signals与以前相同。 换句话说,列A是“开”信号,列B是“关”信号,并且“信号”表示状态。
这是我的代码:
def signals(indata):
numrows = len(indata)
data = pd.DataFrame(index= range(0,numrows))
data['A'] = indata['A']
data['B'] = indata['B']
data['signal'] = 0
for i in range(1,numrows):
if data['A'].iloc[i] == 1:
data['signal'].iloc[i] = 1
elif data['B'].iloc[i] == 1:
data['signal'].iloc[i] = 0
else:
data['signal'].iloc[i] = data['signal'].iloc[i-1]
return data
输入/输出示例:
indata = pd.DataFrame(index = range(0,10))
indata['A'] = [0, 1, 0, 0, 0, 0, 1, 0, 0, 0]
indata['B'] = [1, 0, 0, 0, 1, 0, 0, 0, 1, 1]
signals(indata)
输出:
A B signal
0 0 1 0
1 1 0 1
2 0 0 1
3 0 0 1
4 0 1 0
5 0 0 0
6 1 0 1
7 0 0 1
8 0 1 0
9 0 1 0
这种简单的逻辑使我的计算机需要46秒才能在具有随机生成的数据的2000行数据帧上运行。
df['signal'] = df.A.groupby((df.A != df.B).cumsum()).transform('head', 1)
df
A B signal
0 0 1 0
1 1 0 1
2 0 0 1
3 0 0 1
4 0 1 0
5 0 0 0
6 1 0 1
7 0 0 1
8 0 1 0
9 0 1 0
这里的逻辑涉及根据A
和B
之间的不等式将序列划分为组,每个组的值由A
决定。
您完全不需要迭代就可以执行一些布尔索引
#set condition for A
indata.loc[indata.A == 1,'signal'] = 1
#set condition for B
indata.loc[indata.B == 1,'signal'] = 0
#forward fill NaN values
indata.signal.fillna(method='ffill',inplace=True)
解决我的问题的最简单答案是在遍历数据帧时不写入数据帧。 我在numpy中创建了一个零数组,然后在该数组中执行了迭代逻辑。 然后,将数组写入数据框的列中。
def signals3(indata):
numrows = len(indata)
data = pd.DataFrame(index= range(0,numrows))
data['A'] = indata['A']
data['B'] = indata['B']
out_signal = np.zeros(numrows)
for i in range(1,numrows):
if data['A'].iloc[i] == 1:
out_signal[i] = 1
elif data['B'].iloc[i] == 1:
out_signal[i] = 0
else:
out_signal[i] = out_signal[i-1]
data['signal'] = out_signal
return data
在2000行随机数据的数据帧上,这只需要43毫秒,而不是46秒(快1000倍)。
我还尝试了一个变体,在该变体中,我将数据帧的A列和B列分配给了系列,然后遍历该系列。 这有点快(27毫秒)。 但是看来,大多数的慢是写数据帧。
Coldspeed和djk的答案都比我的解决方案快(约4.5毫秒),但实际上,即使不是最佳选择,我也可能会迭代整个序列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.