为了账号安全,请及时绑定邮箱和手机立即绑定

Pandas:根据复杂的逻辑删除具有特定字符串的行和列

Pandas:根据复杂的逻辑删除具有特定字符串的行和列

杨魅力 2023-10-31 21:18:01
下面是我的数据框:df = pd.DataFrame({'A': ['a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'all', 'all', 'all', 'all', 'all', 'all', 'all', 'all', 'all'],              'B': ['b1', 'b1', 'b1', 'b2', 'b2', 'b2', 'all', 'all', 'all', 'b1', 'b1', 'b1', 'b2', 'b2', 'b2', 'all', 'all', 'all'],              'C': ['c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all'],              'D': ['D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all'],              'E': ['E1', 'E1', 'E1', 'E2', 'E2', 'E2', 'all', 'all', 'all', 'E1', 'E1', 'E1', 'E2', 'E2', 'E2', 'all', 'all', 'all'],              'F': [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]})之后pivot,以下是输出:In [226]: df.pivot(index=['A', 'B', 'C'], columns=['E', 'D'])Out[226]:                F                          (NO)  (NO)           E             E1   E1  E1    E2   E2  E2   all  all  all      D             D1   D2  all   D1   D2  all   D1   D2  allA   B   C                                               a1  all all  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  9.0 a1  all c1   NaN  NaN  NaN  NaN  NaN  NaN  7.0  NaN  NaN  -> (NO)a1  all c2   NaN  NaN  NaN  NaN  NaN  NaN  NaN  8.0  NaN  -> (NO)a1  b1  all  NaN  NaN  3.0  NaN  NaN  NaN  NaN  NaN  NaNa1  b1  c1   1.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaNa1  b1  c2   NaN  2.0  NaN  NaN  NaN  NaN  NaN  NaN  NaNa1  b2  all  NaN  NaN  NaN  NaN  NaN  6.0  NaN  NaN  NaNa1  b2  c1   NaN  NaN  NaN  4.0  NaN  NaN  NaN  NaN  NaNa1  b2  c2   NaN  NaN  NaN  NaN  5.0  NaN  NaN  NaN  NaNall all all  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  9.0我需要删除我指出的行和列(NO)。逻辑是:从最里面的索引开始,即,C我需要保留all以向后方式出现的行和列。因此,具有索引a1 all all、a1 b1 all和a1 b2 all的行将all all all被保留,因为all它们以向后的方式发生。需要删除具有索引a1 all c1、a1 all c2、all all c1、等的行,因为从 向后开始不存在连续性。all b1 allallC同样的逻辑也适用于列。从 开始D,需要删除索引为 的列D1 all,D2 all剩下的就可以了。
查看完整描述

1 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

index为并columns使用 helperDataFrame的最后一次传递创建掩码DataFrame.loc

df1 = df.index.to_frame()

m1 = df1.where(df1=='all').bfill(axis=1).count(axis=1).isin([0, df.index.nlevels])

df2 = df.columns.to_frame()

m2 = df2.where(df2=='all').bfill(axis=1).count(axis=1).isin([0, df.columns.nlevels])


df = df.loc[m1, m2]

print (df)    

                F                              

E             E1             E2            all

D             D1   D2  all   D1   D2  all  all

A   B   C                                     

a1  all all  NaN  NaN  NaN  NaN  NaN  NaN  9.0

    b1  all  NaN  NaN  3.0  NaN  NaN  NaN  NaN

        c1   1.0  NaN  NaN  NaN  NaN  NaN  NaN

        c2   NaN  2.0  NaN  NaN  NaN  NaN  NaN

    b2  all  NaN  NaN  NaN  NaN  NaN  6.0  NaN

        c1   NaN  NaN  NaN  4.0  NaN  NaN  NaN

        c2   NaN  NaN  NaN  NaN  5.0  NaN  NaN

all all all  NaN  NaN  NaN  NaN  NaN  NaN  9.0

    b1  all  NaN  NaN  3.0  NaN  NaN  NaN  NaN

    b2  all  NaN  NaN  NaN  NaN  NaN  6.0  NaN

 

详情:


用于:MultiIndex.to_frame_DataFrame


print (df.index.to_frame())    


               A    B    C

A   B   C                 

a1  all all   a1  all  all

        c1    a1  all   c1

        c2    a1  all   c2

    b1  all   a1   b1  all

        c1    a1   b1   c1

        c2    a1   b1   c2

    b2  all   a1   b2  all

        c1    a1   b2   c1

        c2    a1   b2   c2

all all all  all  all  all

        c1   all  all   c1

        c2   all  all   c2

    b1  all  all   b1  all

        c1   all   b1   c1

        c2   all   b1   c2

    b2  all  all   b2  all

        c1   all   b2   c1

        c2   all   b2   c2

然后将非替换all为缺失值DataFrame.where:


print (df1.where(df1=='all'))

               A    B    C

A   B   C                 

a1  all all  NaN  all  all

        c1   NaN  all  NaN

        c2   NaN  all  NaN

    b1  all  NaN  NaN  all

        c1   NaN  NaN  NaN

        c2   NaN  NaN  NaN

    b2  all  NaN  NaN  all

        c1   NaN  NaN  NaN

        c2   NaN  NaN  NaN

all all all  all  all  all

        c1   all  all  NaN

        c2   all  all  NaN

    b1  all  all  NaN  all

        c1   all  NaN  NaN

        c2   all  NaN  NaN

    b2  all  all  NaN  all

        c1   all  NaN  NaN

        c2   all  NaN  NaN

回填无误,在这里all,由bfill:


print (df1.where(df1=='all').bfill(axis=1))

               A    B    C

A   B   C                 

a1  all all  all  all  all

        c1   all  all  NaN

        c2   all  all  NaN

    b1  all  all  all  all

        c1   NaN  NaN  NaN

        c2   NaN  NaN  NaN

    b2  all  all  all  all

        c1   NaN  NaN  NaN

        c2   NaN  NaN  NaN

all all all  all  all  all

        c1   all  all  NaN

        c2   all  all  NaN

    b1  all  all  all  all

        c1   all  NaN  NaN

        c2   all  NaN  NaN

    b2  all  all  all  all

        c1   all  NaN  NaN

        c2   all  NaN  NaN

通过以下方式计算非缺失值DataFrame.count:


print (df1.where(df1=='all').bfill(axis=1).count(axis=1))

A    B    C  

a1   all  all    3

          c1     2

          c2     2

     b1   all    3

          c1     0

          c2     0

     b2   all    3

          c1     0

          c2     0

all  all  all    3

          c1     2

          c2     2

     b1   all    3

          c1     1

          c2     1

     b2   all    3

          c1     1

          c2     1

测试是否0- 这意味着回填行/列,以及是否全部NaN与级别数匹配MultiIndex.nlevels:


print (df1.where(df1=='all').bfill(axis=1).count(axis=1).isin([0, df.index.nlevels]))

 A    B    C  

a1   all  all     True

          c1     False

          c2     False

     b1   all     True

          c1      True

          c2      True

     b2   all     True

          c1      True

          c2      True

all  all  all     True

          c1     False

          c2     False

     b1   all     True

          c1     False

          c2     False

     b2   all     True

          c1     False

          c2     False

dtype: bool

np.triu编辑:这里是比较的子字符串,然后是仅由 s 行链接创建的辅助数组的掩码的所有值False:


f = lambda x: x.str.contains('all')

arr1 = np.triu(np.ones((df.index.nlevels,df.index.nlevels), dtype=bool), False)

arr2 = np.triu(np.ones((df.columns.nlevels,df.columns.nlevels), dtype=bool), False)

print (arr1)

[[ True  True  True]

 [False  True  True]

 [False False  True]]


arr11 = df.index.to_frame().astype(str).apply(f).to_numpy()

arr22 = df.columns.to_frame().astype(str).apply(f).to_numpy()


#https://stackoverflow.com/a/51352806/2901002

m1 = (arr11[:, None] == arr1).all(-1).any(axis=1) | ~arr11.any(axis=1)

m2 = (arr22[:, None] == arr2).all(-1).any(axis=1) | ~arr22.any(axis=1)


df = df.loc[m1, m2]

print (df) 

                    measure_F                                       

E                          E1             E2                 all  E2

D                          D1   D2  all   D1   D2 all::3::2  all all

A   B   C                                                           

a1  all all               NaN  NaN  NaN  NaN  NaN       NaN  9.0 NaN

    b1  all               NaN  NaN  3.0  NaN  NaN       NaN  NaN NaN

        c1                1.0  NaN  NaN  NaN  NaN       NaN  NaN NaN

        c2                NaN  2.0  NaN  NaN  NaN       NaN  NaN NaN

    b2  all               NaN  NaN  NaN  NaN  NaN       6.0  NaN NaN

        c1                NaN  NaN  NaN  4.0  NaN       NaN  NaN NaN

        c2                NaN  NaN  NaN  NaN  5.0       NaN  NaN NaN

all all all::5::all       NaN  NaN  NaN  NaN  NaN       NaN  9.0 NaN


查看完整回答
反对 回复 2023-10-31
  • 1 回答
  • 0 关注
  • 69 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信