我有一个包含两列的数据框,如下所示:
sap years
a 10
a 5
b 0
c 0
我想要一个具有以下逻辑的函数:
如果两行树液具有相同的值(例如:a和a),并且如果年份中相同的行具有不同的值(例如:10和5),则将行值更改为“错误”
这可能不是该逻辑的正确语法:
import pandas as pd
df = pd.read_excel('gg.xlsx')
groupby_df = df['years'].groupby(df['sap'])
for row in groupby_df:
if row[0] != row[1]:
print("found it")
我尝试过重复,应用和转换,但我想不出解决此问题的解决方案,该方法可以正确比较行。
答案 0 :(得分:0)
如果我理解正确,可能是我先检查一下sap中的哪些行是重复的,而sap + years中的哪些行是重复的:
df['dup_sap'] = df.duplicated(['sap'], keep='first')
df['dup_sap_years'] = df.duplicated(['sap', 'years'], keep='first')
您现在将得到类似的内容:
sap years dup_sap dup_sap_years
0 a 10 False False
1 a 5 True False
2 b 0 False False
3 c 0 False False
从上面可以明显看出第二行中存在不匹配,因此我将其标记为错误:
import numpy as np
df['Error_Flag'] = np.where((df.dup_sap == True) & (df.dup_sap_years == False), 'Yes', 'No')
最终输出:
sap years dup_sap dup_sap_years Error_Flag
0 a 10 False False No
1 a 5 True False Yes ##### this one marked as error
2 b 0 False False No
3 c 0 False False No
对于任何想要解决方案的人,这里的ERROR标志必须在较低的值上。
像这样取每组的最小值:
minDf = df.groupby(['sap'])['years'].min().reset_index()
minDf['min_val'] = 1 # create a flag kind of a variable to denote this
现在将它们与原始数据框合并并标记重复项:
merge = pd.merge(df, minDf, on = ['sap', 'years'], how = 'left')
merge['dup_sap'] = df.duplicated(['sap'], keep=False)
merge['dup_sap_years'] = df.duplicated(['sap', 'years'], keep=False)
您应该拥有一个如下数据框:
sap years min_val dup_sap dup_sap_years
0 a 10 NaN True False
1 a 5 1.0 True False
2 b 0 1.0 False False
3 c 0 1.0 False False
现在创建条件来标记错误,如下所示:
merge['Error_Flag'] = np.where((merge.dup_sap == True) & (merge.dup_sap_years == False) & (~merge.min_val.isna()), 'Yes', 'No')
最终输出:
sap years min_val dup_sap dup_sap_years Error_Flag
0 a 10 NaN True False No
1 a 5 1.0 True False Yes
2 b 0 1.0 False False No
3 c 0 1.0 False False No
希望这对其他人有帮助。