簡體   English   中英

按組刪除連續相同的行

[英]remove consecutive identical rows by group

刪除行

  • 具有至少 n (n = 3) 個連續相同的值
  • 在所有 C1 和 C2 列中
  • 行也必須具有相同的組 (ID),並且
  • 它們必須按日期訂購。

假定與缺失日期對應的行與它們之前的行相同 - 因此,一旦它們的數據按 ID 和日期排序,則無需檢查日期是否連續。

我想這樣做的一種方法是忘記分組並考慮列 C1、C2 和 ID 的相同值。

df = pd.DataFrame({'ID': ["A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B"], 
                   'Date':  [pd.Timestamp('2019-07-12 01:00:00'),
                             pd.Timestamp('2019-07-13 01:00:00'),
                             pd.Timestamp('2019-07-14 01:00:00'),
                             pd.Timestamp('2019-07-15 01:00:00'),
                             pd.Timestamp('2019-07-16 01:00:00'),
                             pd.Timestamp('2019-07-17 01:00:00'), 
                             pd.Timestamp('2019-06-21 01:00:00'), 
                             pd.Timestamp('2019-07-12 01:00:00'),
                             pd.Timestamp('2019-07-13 01:00:00'),
                             pd.Timestamp('2019-07-14 01:00:00'),
                             pd.Timestamp('2019-07-16 01:00:00'),
                             pd.Timestamp('2019-07-17 01:00:00'),
                             pd.Timestamp('2019-07-18 01:00:00')],
                   'C1':[1.0, 4, 4, 4, 4, 3, 3, 3, 3, 5, 5, 5, 3],
                   'C2':[3.0, 4, 4, 4, 3, 3, 3, 3, 5, 5, 5, 5, 3]})

期望的結果是

 ID Date C1 C2 0 A 2019-07-12 01:00:00 1.0 3.0 4 A 2019-07-16 01:00:00 4.0 3.0 5 A 2019-07-17 01:00:00 3.0 3.0 6 B 2019-06-21 01:00:00 3.0 3.0 7 B 2019-07-12 01:00:00 3.0 3.0 8 B 2019-07-13 01:00:00 3.0 5.0 12 B 2019-07-18 01:00:00 3.0 3.0

你可以試試這個邏輯:

grp = (df.groupby(['ID'])['C2'].diff() != 0).cumsum()

mask = df.groupby(grp)['C2'].transform(lambda x: (x.count() < 3) | (x.notna().cumsum() > 3))

df[mask]

Output:

  ID                Date   C1   C2
0   A 2019-07-12 01:00:00  1.0  3.0
4   A 2019-07-16 01:00:00  4.0  3.0
5   A 2019-07-17 01:00:00  3.0  3.0
6   B 2019-06-21 01:00:00  3.0  3.0
7   B 2019-07-12 01:00:00  3.0  3.0
11  B 2019-07-17 01:00:00  5.0  5.0
12  B 2019-07-18 01:00:00  3.0  3.0

細節:

首先我們先groupby ID,計算連續行之間的diff,現在diff不等於1,然后用cumsum定義一組連續相同的值。

接下來,使用第一步定義的組對 dataframe、df 進行分組。 在沒有 NaN 的任何列上使用轉換,您可以獲得組的大小並使用 notna 和 cumsum 來獲得運行計數。

您應該打破此編碼並查看每個步驟的輸出。

你首先需要 agg

代碼:

import pandas as pd

df = pd.DataFrame({'ID': ["A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B"], 
                   'Date':  [pd.Timestamp('2019-07-12 01:00:00'),
                             pd.Timestamp('2019-07-13 01:00:00'),
                             pd.Timestamp('2019-07-14 01:00:00'),
                             pd.Timestamp('2019-07-15 01:00:00'),
                             pd.Timestamp('2019-07-16 01:00:00'),
                             pd.Timestamp('2019-07-17 01:00:00'), 
                             pd.Timestamp('2019-06-21 01:00:00'), 
                             pd.Timestamp('2019-07-12 01:00:00'),
                             pd.Timestamp('2019-07-13 01:00:00'),
                             pd.Timestamp('2019-07-14 01:00:00'),
                             pd.Timestamp('2019-07-16 01:00:00'),
                             pd.Timestamp('2019-07-17 01:00:00'),
                             pd.Timestamp('2019-07-18 01:00:00')],
                   'C1':[1.0, 4, 4, 4, 4, 3, 3, 3, 3, 5, 5, 5, 3],
                   'C2':[3.0, 4, 4, 4, 3, 3, 3, 3, 5, 5, 5, 5, 3]})

df2 = df.groupby(['ID', 'C1', 'C2']).agg({'Date' : 'first'}).reset_index()
print(df2)

Output:

  ID   C1   C2                Date
0  A  1.0  3.0 2019-07-12 01:00:00
1  A  3.0  3.0 2019-07-17 01:00:00
2  A  4.0  3.0 2019-07-16 01:00:00
3  A  4.0  4.0 2019-07-13 01:00:00
4  B  3.0  3.0 2019-06-21 01:00:00
5  B  3.0  5.0 2019-07-13 01:00:00
6  B  5.0  5.0 2019-07-14 01:00:00

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM