【问题标题】:Extract rows based on patterns in data frame根据数据框中的模式提取行
【发布时间】:2020-03-08 07:47:22
【问题描述】:

我正在学习 Python,并且正在研究这样一个数据集:

**Col1**                                 **Col2**      **Col3**      **Col4**  
dog                                        Z             st02          0
dog,cat                                    Z             st02          1
dog,bat,cat                                Z             st02          2
bat,cat,elephant                           Y             st02          2
dog,bat,cat,elephant                       Y             st02          3
tiger                                      Z             st01          0
lion,leopard,cheetah                       Z             st01          2
tiger,lion,leopard,cheetah                 Z             st01          3
dog,tiger,cheetah                          Y             st01          2
dog,tiger,leopard,cheetah                  Y             st01          3
eagle,jaguar,Kangaroo,zebra                Z             st02          3
cheetah,eagle,jaguar,Kangaroo,zebra        Z             st02          4

预期的输出是:

**Col1**                                 **Col2**       **Col3**      **Col4**
dog,bat,cat                                Z              st02          2
dog,bat,cat,elephant                       Y              st02          3
tiger,lion,leopard,cheetah                 Z              st01          3
dog,tiger,leopard,cheetah                  Y              st01          3
cheetah,eagle,jaguar,Kangaroo,zebra        Z              st02          4

为了提取上述行作为输出,我尝试跟踪模式并使用以下逻辑:

data = pd.read_excel("data.xlsx")
data['Col4'] = data['Col1'].str.count(',')
v1 = []
v2 = []
v1.append(0)
v2.append(0)
for i in range(0,data.shape[0]-1):
    x = data['Col_2'][i]
    y = data['Col_2'][i+1]
    t1 = data['Col_3'][i]
    t2 = data['Col_3'][i+1]
    g1 = (x == y) & (t1==t2)
    d1 = data['Col_1'][i]
    d2 = data['Col_1'][i+1]
    c1 = data['Col_4'][i]
    c2 = data['Col_4'][i+1]
    flag = 0
    if(all(x in d2 for x in d1)):
      flag = 1
    g2 = (flag == 1)&(c2>c1)
    v1.append(g1)
    v2.append(g2)
    data['new_cond1'] = v1   
    data['new_cond2'] = v2   
    data['Final_flag'] = (data['new_cond1']==True)&(data['new_cond2']==True) 
    data_output = data[data['Final_flag']==True]  

但我最终没有得到预期的输出,而是输出中还存在一些额外的行。有人可以帮我提取预期输出中提到的行。

更新 2:

当我将以下内容添加到上述数据框时:

**Col1**                                 **Col2**      **Col3**      **Col4**  
  pigeon                                   Z             st01          0
  pigeon,parrot                            Z             st01          1
  dove,parrot                              Z             st01          1
  pigeon,parrot                            Z             st01          1
  pigeon,parrot,dove                       Z             st01          2

预期的结果还包括:

pigeon,parrot,dove                         Z             st01          2

虽然 "pigeon,parrot,dove" 行的 max(Col4) 不大于连续组内的最大计数 (Col4),但它仍包含在输出中。 我认为这是因为 Col1 的类别也很重要。也就是说,由于新添加的行具有不同类别的单词“pigeon,parrot,dove”。

提前致谢!

【问题讨论】:

    标签: python pandas dataframe design-patterns


    【解决方案1】:

    如果想要Col2Col2Col3 的每个连续组的Col1 中的最大, 行,请使用:

    g = df[['Col2','Col3']].ne(df[['Col2','Col3']].shift()).any(1).cumsum()
    df1 = df.loc[df.groupby(g)['Col4'].idxmax()]
    print (df1)
                                       Col1 Col2  Col3  Col4
    2                           dog,bat,cat    Z  st02     2
    4                  dog,bat,cat,elephant    Y  st02     3
    7            tiger,lion,leopard,cheetah    Z  st01     3
    9             dog,tiger,leopard,cheetah    Y  st01     3
    11  cheetah,eagle,jaguar,Kangaroo,zebra    Z  st02     4
    

    编辑:

    df = pd.DataFrame({'Col1': ['dog', 'dog,cat', 'dog,bat,cat', 'bat,cat,elephant', 'dog,bat,cat,elephant', 'tiger', 'lion,leopard,cheetah', 'tiger,lion,leopard,cheetah', 'dog,tiger,cheetah', 'dog,tiger,leopard,cheetah', 'eagle,jaguar,Kangaroo,zebra', 'cheetah,eagle,jaguar,Kangaroo,zebra', 'pigeon', 'pigeon,parrot', 'dove,parrot', 'pigeon,parrot', 'pigeon,parrot,dove'], 'Col2': ['Z', 'Z', 'Z', 'Y', 'Y', 'Z', 'Z', 'Z', 'Y', 'Y', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z', 'Z'], 'Col3': ['st02', 'st02', 'st02', 'st02', 'st02', 'st01', 'st01', 'st01', 'st01', 'st01', 'st02', 'st02', 'st01', 'st01', 'st01', 'st01', 'st01'], 'Col4': [0, 1, 2, 2, 3, 0, 2, 3, 2, 3, 3, 4, 0, 1, 1, 1, 2]})
    

    print (df)
                                       Col1 Col2  Col3  Col4
    0                                   dog    Z  st02     0 <group1
    1                               dog,cat    Z  st02     1
    2                           dog,bat,cat    Z  st02     2
    
    3                      bat,cat,elephant    Y  st02     2 <group2
    4                  dog,bat,cat,elephant    Y  st02     3
    
    5                                 tiger    Z  st01     0 <group3
    6                  lion,leopard,cheetah    Z  st01     2
    7            tiger,lion,leopard,cheetah    Z  st01     3
    
    8                     dog,tiger,cheetah    Y  st01     2 <group4
    9             dog,tiger,leopard,cheetah    Y  st01     3
    
    10          eagle,jaguar,Kangaroo,zebra    Z  st02     3 <group5
    11  cheetah,eagle,jaguar,Kangaroo,zebra    Z  st02     4
    
    12                               pigeon    Z  st01     0 <group6
    13                        pigeon,parrot    Z  st01     1
    14                          dove,parrot    Z  st01     1
    15                        pigeon,parrot    Z  st01     1
    16                   pigeon,parrot,dove    Z  st01     2
    

    g = df[['Col2','Col3']].ne(df[['Col2','Col3']].shift()).any(1).cumsum()
    df1 = df.loc[df.groupby(g)['Col4'].idxmax()]
    print (df1)
                                       Col1 Col2  Col3  Col4
    2                           dog,bat,cat    Z  st02     2
    4                  dog,bat,cat,elephant    Y  st02     3
    7            tiger,lion,leopard,cheetah    Z  st01     3
    9             dog,tiger,leopard,cheetah    Y  st01     3
    11  cheetah,eagle,jaguar,Kangaroo,zebra    Z  st02     4
    16                   pigeon,parrot,dove    Z  st01     2
    

    【讨论】:

    • 非常感谢@jezrael。请有一个小小的疑问,如果它是基于 Col1 的最大值提取的,每组按 Col2 和 Col3,对于特定的 Col2 值“Z”和 Col3 值“st02”,预期输出中有 2 行。示例是 行号。 2第 11 行。那么我们是否也基于 Col1 提取行?因为 行中的“狗、蝙蝠、猫”。与来自 row no.11 的 max(逗号)值为“4”。两者属于同一组。
    • @pc_pyr - 区别是per consecutive groups - 这意味着我区分了相同的组,因为不是连续的。如果需要相同,请使用df1 = df.loc[df.groupby(['Col2','Col3'])['Col4'].idxmax()]
    • 当我尝试使用之前使用的方法时,它没有使用 "pigeon,parrot,dove" 获取行。我们是否也应该考虑 Col1 的类别。因为当添加新的单词类别并且如果它们的计数(逗号)
    • @pc_pyr - 因为每个组的最大 col4 只有一行 col2, col3
    • 我对新添加的行也使用了“每个连续组”方法@jezrael。但输出似乎不包括 "pigeon,parrot,dove" row
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    • 2021-11-27
    • 2021-09-20
    • 2016-12-11
    相关资源
    最近更新 更多