【问题标题】:How to remove rows from a DataFrame where some columns only have zero values如何从 DataFrame 中删除某些列只有零值的行
【发布时间】:2020-12-01 07:13:59
【问题描述】:

我在 Python 中有以下 Pandas DataFrame:

import numpy as np
import pandas as pd
df  = pd.DataFrame(np.array([[1, 2, 3, 4, 5, 6], [11, 22, 33, 44, 55, 66], 
                             [111, 222, 0, 0, 0, 0], [1111, 0, 0, 0, 0, 0]]),
                   columns=['a', 'b', 'c', 'd', 'e', 'f'])

DataFrame 在表格中如下所示:

    a      b     c    d     e    f
0   1      2     3    4     5    6
1   11     22    33   44    55   66
2   111    222   0    0     0    0
3   1111   2222  0    0     0    0

原来的 DataFrame 比这个大得多。正如所见,某些行在某些列中的值为零(c、d、e、f)。

我需要从 DataFrame 中删除这些列,以便我的新 DataFrame 如下所示(在删除给定列仅为零的行之后):

    a      b     c    d     e    f
0   1      2     3    4     5    6
1   11     22    33   44    55   66

我只需要删除所有这些列(c、d、e 和 f)都为零的行。例如,如果其中 2 个为 0,那么我不会删除这些行。

有没有一种不循环DataFrame的好方法来做这个操作?

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    试试这个,

    df[~df[list('cdef')].eq(0).all(axis = 1)]
    

        a   b   c   d   e   f
    0   1   2   3   4   5   6
    1  11  22  33  44  55  66
    

    【讨论】:

    • 感谢您的回答。此代码删除任何列为零的任何行。如果一列或两列为零,则可以。但就我而言,所有 c、d、e、f 列都必须为零。立即更新问题。
    • @edn,c,d,e,f 上的布尔掩码,后跟带有 axis=1all,以确保所有值都为真。
    • 感谢@Sushanth 的回答。
    【解决方案2】:

    对选定列进行行过滤,任何带有any 的列都为零:

    import numpy as np
    import pandas as pd
    
    df  = pd.DataFrame(np.array([[1, 2, 3, 4, 5, 6], [11, 22, 33, 44, 55, 66],
                                 [111, 222, 0, 0, 0, 0], [1111, 0, 0, 0, 0, 0]]),
                       columns=['a', 'b', 'c', 'd', 'e', 'f'])
    
    df = df[(df[['c', 'd', 'e', 'f']] != 0).any(axis=1)]
    
    print(df)
    

    输出:

        a   b   c   d   e   f
    0   1   2   3   4   5   6
    1  11  22  33  44  55  66
    

    【讨论】:

    • 感谢您的回答。该解决方案只需要删除所有给定列为零的行。例如,如果其中 3 个为零,则代码不应触及此类行。我通过将第 3 行更改为 [111, 222, 333, 0, 0, 0] 来尝试您的解决方案,但它也删除了这一行,但需要将其留在表格中。
    • @edn 刚刚修复。
    【解决方案3】:

    这里还有一个选项: 将df.query() 与自定义查询一起使用。

    my_query = '~('+'and '.join([f'{name}==0' for name in 'cdef'])+')'
    df.query(my_query)
    

    如果您打印my_query,则很容易阅读: ~(c==0 and d==0 and e==0 and f==0) ~ 表示“不”。

    【讨论】:

      【解决方案4】:

      带操作员

      df.loc[~((((df['c'] == 0) & (df['d'] == 0)) & (df['e'] == 0)) & (df['f'] == 0))]
      

      【讨论】:

        猜你喜欢
        • 2018-02-01
        • 2018-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-31
        • 2017-11-05
        相关资源
        最近更新 更多