基于前一行的唯一行数-熊猫

时间:2019-11-12 00:16:41

标签: python pandas pandas-groupby

我想从df中的多个列中返回唯一行。问题是,如果它们没有出现在上一行中,则我想包含相同的一组值。这有点难以解释,所以我将显示它;

df = pd.DataFrame({   
        'Time' : ['2019-08-02 09:50:10.1','2019-08-02 09:50:10.2','2019-08-02 09:50:10.3','2019-08-02 09:50:10.4','2019-08-02 09:50:10.5','2019-08-02 09:50:10.6','2019-08-02 09:50:10.7','2019-08-02 09:50:10.8','2019-08-02 09:50:10.9','2019-08-02 09:50:11.0'],
        'Code1' : ['A','A','B','B','C','C','A','A','B','B'],    
        'Code2' : ['B','B','A','A','B','B','B','B','A','A'],    
        'Code3' : [np.nan,np.nan,'C','C','A','A','C','C','C','C'],                                   
        })


df = df[df.iloc[:, 1:].shift().ne(df.iloc[:, 1:]).any(axis=1)].reset_index(drop = True)

预期输出:

                    Time Code1 Code2 Code3
0  2019-08-02 09:50:10.1     A     B   NaN
1  2019-08-02 09:50:10.3     B     A     C
2  2019-08-02 09:50:10.5     C     B     A
3  2019-08-02 09:50:10.7     A     B     C
4  2019-08-02 09:50:10.9     B     A     C

2 个答案:

答案 0 :(得分:1)

首先,我们使用iloc选择正确的列,然后使用shift检查当前行是否不等于下一行。最后,我们在any上使用axis=1 (columns)。因为A B CB A C不同,但是有C共同点:

df[df.iloc[:, 1:].shift().ne(df.iloc[:, 1:]).any(axis=1)]

还是一样,但要简洁一点:

mask = df.iloc[:, 1:].shift().ne(df.iloc[:, 1:])
df[mask.any(axis=1)]
                    Time Code1 Code2 Code3
0  2019-08-02 09:50:10.1     A     B     C
2  2019-08-02 09:50:10.3     B     A     C
4  2019-08-02 09:50:10.5     C     B     A
6  2019-08-02 09:50:10.7     A     B     C
8  2019-08-02 09:50:10.9     B     A     C

答案 1 :(得分:1)

您可以为空值使用前哨值,然后对结果进行分组。

groupbyshift-cumsum pattern的变体。

sentinel = 99999999
mask = df[cols].fillna(sentinel).ne(df[cols].fillna(sentinel).shift())
>>> df.groupby(
        mask.any(axis=1).cumsum(), 
        sort=False,
        as_index=False
    ).first()
                    Time Code1 Code2 Code3
0  2019-08-02 09:50:10.1     A     B   NaN
1  2019-08-02 09:50:10.3     B     A     C
2  2019-08-02 09:50:10.5     C     B     A
3  2019-08-02 09:50:10.7     A     B     C
4  2019-08-02 09:50:10.9     B     A     C