我有一组非常大的数据帧,我想根据前面的行值和索引遵循一些逻辑进行修改。
如果值在要删除的值列表中,并且前一行的值不在要删除的值列表中,并且这两行具有相同的索引,则将前一个值分配给当前值。基本上我可以把它写成for循环并以下列方式获得所需的输出:
import pandas as pd
df = pd.DataFrame({'values': [1,2,3,4,2,4,4,1,2]},index=['A','A','A','A','B','B','B','C','C'])
print(df)
rem_val = [2,3]
for i in range(1,len(df)):
if df['values'].iloc[i] in rem_val and df['values'].iloc[i-1] not in rem_val and df.index[i-1]==df.index[i]:
df['values'].iloc[i]=df['values'].iloc[i-1]
print('After removal')
print(df)
输出为
values
A 1
A 2
A 3
A 4
B 2
B 4
B 4
C 1
C 2
After removal
values
A 1
A 1
A 1
A 4
B 2
B 4
B 4
C 1
C 1
请注意,例如,B的第一行是2(在要删除的列表中)但是因为在它之前没有B的行而停留。
不幸的是,这是一个相对较慢的代码(有数十亿行),但我不确定如何对其进行矢量化/更快。其中一个问题是,可能需要调整一行中有很多(10s)坏行,因此您无法将[:-1]与[1:]进行比较。有没有办法对上面的for循环进行矢量化/加速?
谢谢,
伊利亚安德
答案 0 :(得分:1)
如果我理解清楚,请使用groupby
+ mask
+ isin
df.mask(df['values'].isin(rem_val)).groupby(level=0).ffill().combine_first(df)
Out[1572]:
values
A 1.0
A 1.0
A 1.0
A 4.0
B 2.0
B 4.0
B 4.0
C 1.0
C 1.0