Количество уникальных строк на основе предыдущего ряда - Панды - PullRequest
0 голосов
/ 12 ноября 2019

Я хочу вернуть уникальные строки из нескольких столбцов в 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 ]

1 голос
/ 12 ноября 2019

Вы можете использовать значение часового для нулей, а затем сгруппировать по результату.

groupby является вариантом шаблона shift-cumsum .

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
1 голос
/ 12 ноября 2019

Сначала мы используем iloc, чтобы выбрать правильные столбцы, затем мы используем shift, чтобы проверить, не совпадает ли текущая строка со следующей. Наконец мы используем any над axis=1 (columns). Потому что A B C и B 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...