Pandas Dataframe:根据条件查找重复行

Pandas Dataframe: Find duplicate rows based on a criteria

我有一个包含以下列和行的数据框:

    State   Rain    Sun     Snow    Day
1   NJ      yes     no      no      5/31/21
2   NJ      yes     no      no      6/1/21
3   NJ      yes     no      no      6/2/21
4   NJ      yes     no      no      6/3/21
5   NY      no      no      yes     5/31/21
6   NY      no      yes     NULL    6/1/21
7   NY      no      yes     NULL    6/2/21
8   NY      no      yes     NULL    6/3/21
9   IL      no      yes     no      5/31/21
10  IL      no      yes     no      6/1/21
11  IL      no      yes     no      6/2/21
12  IL      yes     no      no      6/3/21
13  FL      no      yes     no      5/31/21
14  FL      yes     no      NULL    6/1/21
15  FL      yes     NULL    NULL    6/2/21
16  FL      NULL    NULL    NULL    6/3/21

此处Rain、Sun、Snow列可以为NULL值,但其他列不能为NULL。此外,如果 Rain 列为空,则 Sun 和 Snow 列也将为 NULL,例如:

NJ NULL NULL  NULL 5/31/21 -> Valid
NJ no   yes   NULL 5/31/21 -> Valid
NJ yes  NULL  NULL 5/31/21 -> Valid
NJ NULL yes   no   5/31/21 -> Invalid
NJ yes  NULL  no   5/31/21 -> Invalid
NJ NULL NULL  no   5/31/21 -> Invalid

我想在此数据集中查找重复项,但要符合特定条件和 return 重复值的索引。 以下情况应视为重复:

案例 1:

NJ      yes     no      no      5/31/21
NJ      yes     no      no      5/31/21

案例二:

NY      no      yes     NULL    6/1/21
NY      no      yes     NULL    6/1/21

案例 3:

FL      no      no      no      6/1/21
FL      no      no      NULL    6/1/21
FL      no      NULL    NULL    6/1/21
FL      NULL    NULL    NULL    6/1/21

我能够解决前两种情况:

    def find_duplicates(df: pd.DataFrame):
        dup_rows = df.duplicated(subset=['State', 'Rain', 'Sun', 'Snow', 'Day'], keep=False)
        dup_df = df[dup_rows]
        dup_df = dup_df.reset_index()
        dup_df.rename(columns={'index': 'row'}, inplace=True)
        group = dup_df.groupby(['State', 'Rain', 'Sun', 'Snow', 'Day'], dropna=False)
        dup_lst = [grp['row'].to_list() for ind, grp in group]
        return dup_lst

我不确定如何处理第 3 种情况,我是 pandas 数据框的新手,如有任何帮助,我们将不胜感激。

也许这就是您要找的东西?

import numpy as np
import pandas as pd


def colwise_dups(df, cols):
    return df[
        np.array(
            [
                (row.drop(index=cols).values == df.drop(columns=cols).values).all(
                    axis=1
                )
                for _, row in df[
                    (df[cols] == ["NULL"] * len(cols)).all(axis=1)
                ].iterrows()
            ]
        ).any(axis=0)
    ]


cols = []
duplicates = pd.DataFrame()
for col in ["Rain", "Sun", "Snow"][::-1]:
    cols.append(col)
    duplicates = pd.concat([duplicates, colwise_dups(df, cols)]).drop_duplicates()```

如果我对问题的理解正确,我认为您可以通过创建两个分别用 'NULL' 替换为 'yes' 和 'no' 的临时数据框来实现您的目标。然后您可以根据重复项进行过滤。

最小示例:

df = pd.DataFrame({'State': 'NJ NJ NY NY FL FL FL FL'.split(' '),
              'Rain': 'yes yes no no no no no NULL'.split(' '),
              'Sun': 'no no yes yes no no NULL NULL'.split(' '),
              'Snow': 'no no NULL NULL no NULL NULL NULL'.split(' '),
              'Day': '5/31/21 5/31/21 6/1/21 6/1/21 6/1/21 6/1/21 6/1/21 6/1/21' .split(' ')})

tmp = df.replace('NULL', 'no')
tmp2 = df.replace('NULL', 'yes')

df[~tmp.duplicated() & ~tmp2.duplicated()]

给出以下输出:


  State Rain  Sun  Snow      Day
0    NJ  yes   no    no  5/31/21
2    NY   no  yes  NULL   6/1/21
4    FL   no   no    no   6/1/21