【问题标题】:Filter down the dataframe based on condition that value in a column is a whole number (integer)根据列中的值是整数(整数)的条件过滤数据框
【发布时间】:2018-11-29 17:31:02
【问题描述】:

我正在努力过滤我的数据框,因此我只有整数行(如 21.00)。 我看到了一个类似的 QA (Creating new column in pandas df populated by True,False depending on whether another column is a whole number),但这不是我想要实现的。 我试过 float.is_integer(),但这不是 Series 的方法,它必须通过 for 循环逐元素应用。

在我的数据框中,我有这样的列:

index  value
0      43.00 
1      23.47
2       5.31 
3      349.00

我只想提取包含整数的行,因此在上述情况下,我只需要具有以下值的行:43.00 和 349.00。

如果值为整数,如何在不使用 for 循环或添加带有指示变量的新列的情况下完成?

我的数据框有数千万行,所以我宁愿避免使用循环或尽可能添加另一列。

【问题讨论】:

    标签: python pandas dataframe floating-point series


    【解决方案1】:

    您可以使用布尔系列来过滤数据框:

    res = df[df['value'].map(lambda x: x.is_integer())]
    
    print(res)
    
       index  value
    0      0   43.0
    3      3  349.0
    

    为了性能,您可能希望将一个系列与其自身的整数版本进行比较:

    res = df[df['value'] == df['value'].astype(int)]
    

    性能基准测试

    成本主要由布尔序列的构造决定。

    df2 = pd.concat([df]*100000)
    
    %timeit df2['value'].values % 1 == 0.0              # 20.8 ms per loop
    %timeit df2['value'] == df2['value'].astype(int)    # 2.59 ms per loop
    %timeit df2['value'].map(lambda x: x.is_integer())  # 195 ms per loop
    %timeit ~(df2['value'] % 1).astype(bool)            # 23.3 ms per loop
    %timeit df2['value'] % 1 == 0.0                     # 21.8 ms per loop
    

    版本:

    sys.version     # '3.6.0'
    pd.__version__  # '0.19.2'
    np.__version__  # '1.11.3'
    

    【讨论】:

    • 其实想想df2['value'].values % 1 == 0.0可能更快。
    • @ScottBoston,嗯,不幸的是,与pd.Series.astype(int) 相比,我没有看到这一点。我已经更新了额外的时间。
    • Pandas 对象带有开销。使用 numpy 数组几乎总是更快。尤其是在进行这样的比较时。 Pandas 只是更优雅地处理 NaN 和其他事情,但这种优雅已经付出了代价。
    • @ScottBoston,是的,我同意它比 Pandas 版本快一点(~5%)。但它仍然比 df2['value'] == df2['value'].astype(int) 慢约 9 倍。
    • 啊……是的……我明白了。 .astype(int) 是最优的。
    猜你喜欢
    • 2012-12-21
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 2023-01-10
    • 2018-11-12
    • 2017-08-15
    相关资源
    最近更新 更多