首页 > 解决方案 > 如何循环比较一列与其在Python中的对应列

问题描述

我有一个作为数据框导入的 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 中。我希望第 2 列和第 1 列之间的第一次比较结果为:

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 

标签: pythonpandasdataframe

解决方案


就像其中一个评论状态一样,您的预期输出可能会影响最佳解决方案。记住这一点,遍历列很少是最好的解决方案。我建议简单地添加新列来指示被比较的列是否相等。例如:

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

推荐阅读