【问题标题】:Deleting DataFrame rows in Pandas based on column value - multiple values to remove根据列值删除 Pandas 中的 DataFrame 行-要删除的多个值
【发布时间】:2016-11-01 17:23:27
【问题描述】:

我有一个值列表(事先不知道,在 Python 列表中),我的 Panda DataFrame 中的列不能对所有行都有。

网络上的所有食谱(如this one)都展示了如何只排除一个值,但我有多个值要排除。我该怎么做?

请注意,我无法硬编码要在我的代码中排除的值。

谢谢!

【问题讨论】:

标签: python pandas filter dataframe


【解决方案1】:

你可以做否​​定的isin()索引:

In [57]: df
Out[57]:
   a  b  c
0  1  2  2
1  1  7  0
2  3  7  1
3  3  2  7
4  1  3  1
5  3  4  2
6  0  7  1
7  5  4  3
8  6  1  0
9  3  2  0

In [58]: my_list = [1, 7, 8]

In [59]: df.loc[~df.b.isin(my_list)]
Out[59]:
   a  b  c
0  1  2  2
3  3  2  7
4  1  3  1
5  3  4  2
7  5  4  3
9  3  2  0

或使用query()函数:

In [60]: df.query('@my_list not in b')
Out[60]:
   a  b  c
0  1  2  2
3  3  2  7
4  1  3  1
5  3  4  2
7  5  4  3
9  3  2  0

【讨论】:

    【解决方案2】:

    您也可以使用np.in1d。来自https://stackoverflow.com/a/38083418/2336654

    对于您的用例:

    df[~np.in1d(df.b, my_list)]
    

    演示

    from string import ascii_letters, ascii_lowercase, ascii_uppercase
    df = pd.DataFrame({'lower': list(ascii_lowercase), 'upper': list(ascii_uppercase)}).head(6)
    exclude = list(ascii_uppercase[:6:2])
    
    print df
    
      lower upper
    0     a     A
    1     b     B
    2     c     C
    3     d     D
    4     e     E
    5     f     F
    
    print exclude
    
    ['A', 'C', 'E']
    
    print df[~np.in1d(df.upper, exclude)]
    
      lower upper
    1     b     B
    3     d     D
    5     f     F
    

    时间

    各种方法

    有 130 万行,不包括 3 个项目

    130 万行,不包括 12 项

    结论

    显然,isinquery 在这种情况下可以更好地扩展。

    【讨论】:

    • Pandas 使用 np.in1d under the hood。看起来他们优化了它使用np.in1d,只有当它通常是有益的时,这是在大型数据集上。它在您的小型示例数据集上稍快一些,但是当我在具有 6k 行且不包括 6 个字母的类似数据上尝试它时,isin 的速度几乎快了一倍。
    • 另外,我注意到ix 稍微减慢了速度。我将重新运行大型数据集并排除 ix
    • 是的,尽管如此,仍然值得提及np.in1d,因为它通常在其他情况下也很有用。
    • 我刚刚让another comparison for different dtypes - np.in1d() 对于字符串非常很慢,但对于所有数字搜索它都会胜出...
    【解决方案3】:

    我决定添加另一个答案,其中包含不同方法和不同数据类型的时间 - 一个答案太长了......

    针对以下 dtype 的 1M 行 DF 的计时:int32、int64、float64、对象(字符串):

    In [207]: result
    Out[207]:
                                  int32  int64  float  string
    method
    df[~np.in1d(df.col, excl)]      249    271    307    2420
    df[~df.col.isin(excl)]          414    210    514     189
    df.ix[~df.col.isin(excl)]       399    212    553     189
    df.query('@excl not in col')    415    228    563     206
    
    In [208]: result.T
    Out[208]:
    method  df[~np.in1d(df.col, excl)]  df[~df.col.isin(excl)]  df.ix[~df.col.isin(excl)]  df.query('@excl not in col')
    int32                          249                     414                        399                           415
    int64                          271                     210                        212                           228
    float                          307                     514                        553                           563
    string                        2420                     189                        189                           206
    

    原始结果:

    int32:

    In [159]: %timeit df[~np.in1d(df.int32, exclude_int32)]
    1 loop, best of 3: 249 ms per loop
    
    In [160]: %timeit df[~df.int32.isin(exclude_int32)]
    1 loop, best of 3: 414 ms per loop
    
    In [161]: %timeit df.ix[~df.int32.isin(exclude_int32)]
    1 loop, best of 3: 399 ms per loop
    
    In [162]: %timeit df.query('@exclude_int32 not in int32')
    1 loop, best of 3: 415 ms per loop
    

    int64:

    In [163]: %timeit df[~np.in1d(df.int64, exclude_int64)]
    1 loop, best of 3: 271 ms per loop
    
    In [164]: %timeit df[~df.int64.isin(exclude_int64)]
    1 loop, best of 3: 210 ms per loop
    
    In [165]: %timeit df.ix[~df.int64.isin(exclude_int64)]
    1 loop, best of 3: 212 ms per loop
    
    In [166]: %timeit df.query('@exclude_int64 not in int64')
    1 loop, best of 3: 228 ms per loop
    

    float64:

    In [167]: %timeit df[~np.in1d(df.float, exclude_float)]
    1 loop, best of 3: 307 ms per loop
    
    In [168]: %timeit df[~df.float.isin(exclude_float)]
    1 loop, best of 3: 514 ms per loop
    
    In [169]: %timeit df.ix[~df.float.isin(exclude_float)]
    1 loop, best of 3: 553 ms per loop
    
    In [170]: %timeit df.query('@exclude_float not in float')
    1 loop, best of 3: 563 ms per loop
    

    对象/字符串:

    In [171]: %timeit df[~np.in1d(df.string, exclude_str)]
    1 loop, best of 3: 2.42 s per loop
    
    In [172]: %timeit df[~df.string.isin(exclude_str)]
    10 loops, best of 3: 189 ms per loop
    
    In [173]: %timeit df.ix[~df.string.isin(exclude_str)]
    10 loops, best of 3: 189 ms per loop
    
    In [174]: %timeit df.query('@exclude_str not in string')
    1 loop, best of 3: 206 ms per loop
    

    结论:

    np.in1d() - 赢得(int32float64)搜索,但它是 大约。搜索字符串时(与其他人相比)慢 10 倍,因此不要将其用于 object(字符串)和 int64 dtypes!

    设置:

    df = pd.DataFrame({
        'int32':    np.random.randint(0, 10**6, 10),
        'int64':    np.random.randint(10**7, 10**9, 10).astype(np.int64)*10,
        'float':    np.random.rand(10),
        'string':   np.random.choice([c*10 for c in string.ascii_uppercase], 10),
        })
    
    
    df = pd.concat([df] * 10**5, ignore_index=True)
    
    exclude_str = np.random.choice([c*10 for c in string.ascii_uppercase], 100).tolist()
    exclude_int32 = np.random.randint(0, 10**6, 100).tolist()
    exclude_int64 = (np.random.randint(10**7, 10**9, 100).astype(np.int64)*10).tolist()
    exclude_float = np.random.rand(100)
    
    
    In [146]: df.shape
    Out[146]: (1000000, 4)
    
    In [147]: df.info()
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 1000000 entries, 0 to 999999
    Data columns (total 4 columns):
    float     1000000 non-null float64
    int32     1000000 non-null int32
    int64     1000000 non-null int64
    string    1000000 non-null object
    dtypes: float64(1), int32(1), int64(1), object(1)
    memory usage: 26.7+ MB
    
    In [148]: df.head()
    Out[148]:
          float   int32       int64      string
    0  0.221662  283447  6849265910  NNNNNNNNNN
    1  0.276834  455464  8785039710  AAAAAAAAAA
    2  0.517846  618887  8653293710  YYYYYYYYYY
    3  0.318897  363191  2223601320  PPPPPPPPPP
    4  0.323926  777875  5357201380  QQQQQQQQQQ
    

    【讨论】:

      猜你喜欢
      • 2013-08-12
      • 2016-05-05
      • 1970-01-01
      • 2018-04-28
      • 2017-11-20
      • 2017-02-16
      • 2021-11-21
      • 2017-07-07
      • 2022-06-21
      相关资源
      最近更新 更多