Pandas:如何提高性能,比较组内的行

问题描述 投票:0回答:1

我做了一个python程序来比较组内的行。但是性能很差。数据来自变更数据捕获系统。对于每个更改,都有一个 Sequence id 和一个 Operation 编号。对于 Update 操作,有两行:一行 Operation=3(先前值),另一行 Operation=4(新值)。没有变化的列设置为空,但值可以从“Somevalue”变为 NULL,所以我需要比较第 3 行和第 4 行以了解它何时为 Null,因为该值确实为 Null 或因为没有变化。

这是源数据的示例:

Source data

这是所需的输出:

Desired outcome

使用相同的模型数据使用我的代码:

import pandas as pd
import numpy as np
d={'_Change-Sequence':[1,1,2,2,3,3],
   '_Operation':[3,4,3,4,3,4],
   'Dossier_x':[1,1,2,2,3,3],
   'IsCovidPositiv':['Yes','No','No',np.NaN,'Yes','Yes'],
   'Status':[np.NaN,'KO',np.NaN,np.NaN,np.NaN,np.NaN]
  }
df_update=pd.DataFrame(data=d)
print(df_update)
for column in [column for column in df_update.columns if column not in {'index','Dossier_x'} if not column.startswith('_')]:
  column_previous_name=column+"_Previous|"
  df_update[column_previous_name]=df_update.groupby('_Change-Sequence')[column].shift()
  df_update[column]=df_update.apply(lambda x:x[column] if x[column_previous_name]!=x[column]  else np.nan,axis=1)
  df_update.drop(column_previous_name,axis=1,inplace=True)
df_update=df_update[df_update['_Operation']==4]

df_update

在线版代码

输出符合要求。如果每个非元或 PK 列(以“_”或索引和“Dossier_x”开头的列)发生变化,则每组只有一行(相同的更改序列),如果未发生变化,则为 NaN。我需要为每一列都这样做(我事先不知道列的名称)

问候

文森特

该程序正在运行(在问题中)但性能很差。

python pandas dataframe group-by apply
1个回答
0
投票

如果我正确理解了您的逻辑,您可以将代码简化为:

cols = [column for column in df_update.columns if column not in {'index','Dossier_x'}
        if not column.startswith('_')]

# get shifted values
tmp = df_update.groupby('_Change-Sequence')[cols].shift()

# mask equal values and slice
out = df_update.mask(df_update.eq(tmp, axis=0)).loc[df_update['_Operation'].eq(4)]

输出:

   _Change-Sequence  _Operation  Dossier_x IsCovidPositiv Status
1                 1           4          1             No     KO
3                 2           4          2            NaN    NaN
5                 3           4          3            NaN    NaN
© www.soinside.com 2019 - 2024. All rights reserved.