如何在Python中循环比较一列及其对应的列

时间:2019-02-11 11:34:48

标签: python pandas dataframe

我有一个导入为数据框的Excel文件。我想遍历数据框的列。例如,我想比较第二列和第一列,然后比较第三列和第二列。我已经将rule_id列转换为索引。这是数据:

rule_id reqid1  reqid2  reqid3
53139   0         0      1
51181   1         1      0
50412   0         1      1
50356   0         0      1
50239   0         1      0
50238   1         1      0
50014   1         0      1      

这是我正在使用的代码。

for n in fin2.columns[0:]:
    n = 0
    n_int = int(n)
    if ([fin2.iloc[: , n_int+1] != fin2.iloc[: , n_int]]):
        print dframe2

    if ([fin2.iloc[: , n_int+1] == fin2.iloc[: , n_int]]):
        print dframe3
    n = n+1

使用此代码,我只能将第二列与第一列进行比较,将n的值设置为0,并且还应用了逻辑n = n + 1,每当条件满足时,n的值就会递增。您的帮助将不胜感激。 我创建了这两个函数:

def solved_prior(df):
    n = 0
    n_int = int(n)
    df['solved_prior'] = np.where(df.iloc[: , n_int+1] < df.iloc[: , n_int] , 100 , np.nan)
    return df

def repeated_prior(df):
    n = 0
    n_int = int(n)
    df['repeated_prior'] = np.where((df.iloc[: , n_int+1] == df.iloc[: , n_int]) & (df.iloc[: , n_int] == 1) , 1 , np.nan)
    return df

我将这些函数分别存储在daframe2和dataframe3中。我希望第二列和第一列之间的第一次比较结果为:

rule_id reqid1  reqid2  reqid3 solved prior repeated prior
    53139   0         0      1    NaN          NaN
    51181   1         1      0    NaN           1
    50412   0         1      1    NaN          NaN
    50356   0         0      1    NaN          NaN
    50239   0         1      0    NaN          NaN
    50238   1         1      0    NaN           1
    50014   1         0      1    100          NaN 

第3列和第2列之间的比较结果应如下所示:

  rule_id reqid1     reqid2 reqid3 solved prior repeated prior
    53139   0         0      1       NaN          NaN
    51181   1         1      0       100          NaN
    50412   0         1      1       NaN           1
    50356   0         0      1       NaN          NaN
    50239   0         1      0       100          NaN
    50238   1         1      0       NaN          NaN
    50014   1         0      1       NaN          NaN 

1 个答案:

答案 0 :(得分:0)

就像其中一种评论状态一样,您的预期输出可能会影响最佳解决方案。请记住,在列上循环很少是最好的解决方案。我建议简单地添加新列,以指示要比较的列是否相等。例如:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame({'rule_id': [53139,51181,50412,50356,50239,50238,50014], 'reqid1':[0,1,0,0,0,1,1],'reqid2':[0,1,1,0,1,1,0],'reqid3':[1,0,1,1,0,0,1]})

In [3]: df
Out[3]: 
   rule_id  reqid1  reqid2  reqid3
0    53139       0       0       1
1    51181       1       1       0
2    50412       0       1       1
3    50356       0       0       1
4    50239       0       1       0
5    50238       1       1       0
6    50014       1       0       1

In [4]: df['compare_1_and_2'] = df.reqid1 == df.reqid2

In [5]: df
Out[5]: 
   rule_id  reqid1  reqid2  reqid3  compare_1_and_2
0    53139       0       0       1             True
1    51181       1       1       0             True
2    50412       0       1       1            False
3    50356       0       0       1             True
4    50239       0       1       0            False
5    50238       1       1       0             True
6    50014       1       0       1            False

In [6]: df['compare_2_and_3'] = df.reqid2 == df.reqid3

In [7]: df
Out[7]: 
   rule_id  reqid1  reqid2  reqid3  compare_1_and_2  compare_2_and_3
0    53139       0       0       1             True            False
1    51181       1       1       0             True            False
2    50412       0       1       1            False             True
3    50356       0       0       1             True            False
4    50239       0       1       0            False            False
5    50238       1       1       0             True            False
6    50014       1       0       1            False            False

现在,如果列很长,您可能会发现any()和all()有用。查看是否有任何值是真的(至少有一个相同的值):

In [8]: df.compare_1_and_2.any()
Out[8]: True

并查看所有值是否均为真(各列相同):

In [9]: df.compare_1_and_2.all()
Out[9]: False

编辑:(以匹配预期的输出) 现在,只需使用布尔列来匹配您所需的内容即可

df['solved_prior_1_vs_2'] = np.NaN
df['repeated_prior_1_vs_2'] = np.NaN
df.loc[(df.compare_1_and_2 == False) & (df.reqid1 == 1),'solved_prior_1_vs_2'] = 100
df.loc[(df.compare_1_and_2 == True) & (df.reqid1 == 1),'repeated_prior_1_vs_2'] = 1

结果如下:

In [27]: df[['rule_id','reqid1','reqid2','solved_prior_1_vs_2','repeated_prior_1_vs_2']]
Out[27]: 
   rule_id  reqid1  reqid2  solved_prior_1_vs_2  repeated_prior_1_vs_2
0    53139       0       0                  NaN                    NaN
1    51181       1       1                  NaN                    1.0
2    50412       0       1                  NaN                    NaN
3    50356       0       0                  NaN                    NaN
4    50239       0       1                  NaN                    NaN
5    50238       1       1                  NaN                    1.0
6    50014       1       0                100.0                    NaN

您现在可以删除不需要的列,并进行比较以比较2到3。也可以将新列转换为整数。

最终编辑(希望如此): 一个更简单的解决方案是只定义一个函数,例如:

def compare_columns(df, col1, col2):
    repeated_name = "{}_{}_repeated".format(col1, col2)
    solved_name = "{}_{}_solved".format(col1, col2)
    diff = df[col1] == df[col2]
    col1_is_1 = df[col1] == 1
    df[repeated_name] = 100
    df[solved_name] = 1
    df[repeated_name] = df[repeated_name].astype(int)
    df[solved_name] = df[sovled_name].astype(int)
    df.loc[~(diff & col1_is_1), solved_name] = np.NaN
    df.loc[~(~diff & col1_is_1), repeated_name] = np.NaN
    return df

现在您可以这样做:

In [42]: df1 = compare_columns(df, 'reqid1', 'reqid2')
In [43]: df1
Out[43]: 
   rule_id  reqid1  reqid2  reqid3  reqid1_reqid2_repeated  reqid1_reqid2_solved
0    53139       0       0       1                     NaN                   NaN
1    51181       1       1       0                     NaN                   1
2    50412       0       1       1                     NaN                   NaN
3    50356       0       0       1                     NaN                   NaN
4    50239       0       1       0                     NaN                   NaN
5    50238       1       1       0                     NaN                   1
6    50014       1       0       1                     100                   NaN