【问题标题】:Deleting a row based on values of the next row on multiple columns with pandas使用熊猫根据多列下一行的值删除一行
【发布时间】:2018-12-20 20:57:06
【问题描述】:

我想在下一个满足特定条件时从我的数据框中删除行。假设我的数据集是:

raw_data = {'SessionID': ['S1', 'S1', 'S1', 'S2', 'S2', 'S2', 'S2', 'S2', 'S3', 'S3', 'S3', 'S3', 'S3', 'S3'], 
    'Event Action': ['Action', 'Action', 'Filter', 'Action', 'Action', 'Action', 'Filter', 'Filter', 'Action', 'Filter','Action', 'Filter', 'Filter', 'Action'], 
    'Timestamp': ['T1.1', 'T1.2', 'T1.3', 'T1.1', 'T1.2', 'T1.3', 'T1.3', 'T1.4', 'T1.4', 'T1.5', 'T1.7', 'T1.7', 'T1.8', 'T1.9']}

df = pd.DataFrame(raw_data, columns = ['SessionID', 'Event Action', 'Timestamp'])

df

 SessionID  Event Action    Timestamp
0   S1         Action          T1.1
1   S1         Action          T1.2
2   S1         Filter          T1.3
3   S2         Action          T1.1
4   S2         Action          T1.2
5   S2         Action          T1.3
6   S2         Filter          T1.3
7   S2         Filter          T1.4
8   S3         Action          T1.4
9   S3         Filter          T1.5
10  S3         Action          T1.7
11  S3         Filter          T1.7
12  S3         Filter          T1.8
13  S3         Action          T1.9

给定任何 row 并且是 row1 下一个,我想在以下情况下删除 row

if df[row:'SessionID'] == df[row1:'SessionID'] 
and df[row:'Event Action'] == 'Action' 
and df[row1:'Event Action'] == 'Filter' 
and df[row:'Timestamp'] == df[row1:'Timestamp']

例如,在上面的数据集中,应该消除的行是 5 和 10。我不是 Python 方面的专家,但我尝试过:

def cleanfilter(row):
    row1 = row + 1
    if df[row:'SessionID'] == df[row1:'SessionID'] and df[row:'Event Action'] == 'Search Action'and df[row1:'Event Action'] == 'Search Filter' and df[row:'Timestamp'] == df[row1:'Timestamp']:
    df.drop(df.index[row])

df.apply(cleanfilter,axis=1)

但我不断收到:“TypeError:('必须是 str,而不是 int','发生在索引 0')”。我不知道该谷歌了...任何建议将不胜感激!提前致谢。

【问题讨论】:

  • 你是什么意思row1:'SessionID',我没有看到第 1 行
  • 对于糟糕的表述,我深表歉意。 row1 是紧接在 row 之后的行。因此,对于任何特定的 rowrow1 是紧随 row 之后的那个

标签: python pandas


【解决方案1】:

您可以为您的条件创建掩码,然后将它们应用到您的 df 中,因为我们希望删除符合条件的行。

m1 = (df['SessionID'] == df['SessionID'].shift(-1))
m2 = (df['Event Action']=='Action')
m3 = (df['Event Action'].shift(-1)=='Filter')
m4 = (df['Timestamp']==df['Timestamp'].shift(-1))
df[~(m1 & m2 & m3 & m4)]

输出:

         SessionID Event Action Timestamp
0         S1       Action      T1.1
1         S1       Action      T1.2
2         S1       Filter      T1.3
3         S2       Action      T1.1
4         S2       Action      T1.2
6         S2       Filter      T1.3
7         S2       Filter      T1.4
8         S3       Action      T1.4
9         S3       Filter      T1.5
11        S3       Filter      T1.7
12        S3       Filter      T1.8
13        S3       Action      T1.9

【讨论】:

  • 这非常有效,而且比我尝试做的更优雅。我现在已经阅读了 .shift pandas 文档,很酷。但是我没有完全理解最后一句话:df[~(m1 & m2 & m3 & m4)]。这是否意味着:打印不包括这些条件的数据框?
  • @E.Faslo,它返回不满足(m1 & m2 & m3 & m4)(所有条件)的df的副本。而不是删除满足条件的行,我们正在寻找不满足条件的行。我希望它能消除你的疑虑。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
  • 1970-01-01
  • 2016-05-07
  • 2021-12-02
相关资源
最近更新 更多