繁体   English   中英

根据小数点后的值从 Pandas DataFrame 中删除行

[英]Drop rows from Pandas DataFrame based on value after decimal

我有带有值和名称的大 DF。 在以增量 0.1 插入值后,我想删除带有 1111.123 等数字的行,并只保留带有 1111.0、1111.1、1111.2(或 1111.100...)的行

价值 姓名
1111.1 标记
1111.2 标记
1111.234 标记
1111.3 标记
1111.346 标记
1111.4 标记

我已经通过字符串尝试Series.str.split()但对于大于 1 GB 的 CSV 来说太慢了。 我试过正则表达式

m = df['Value'].str.filter(regex='(\d*)\.(\d{3})')

但它返回空系列。

我尝试过的另一个选项是math.modf ,但它返回

ValueError:Series 的真值不明确。 使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。

这是代码本身:

import pandas as pd
from math import modf

df = pd.read_csv("file.csv")

split = ((df['Value'].apply(lambda x: modf(x)[0])) * 10).apply(lambda x: modf(x)[0])
target_value = 0 < split < 1
df1 = df.loc[split == target_value]
*some code to remove rows*

我期望的最终结果是:

价值 姓名
1111.1 标记
1111.2 标记
1111.3 标记
1111.4 标记

如果您不想将浮点数转换为字符串,请使用这个简单的数学技巧来检查第一个后是否有小数:

df[(df['Value']*10%1).eq(0)]

或者,您可以简单地检查倒数第二个字符是否为.

df[df['Value'].astype(str).str[-2].eq('.')]

输出:

    Value  Name
0  1111.1  Mark
1  1111.2  Mark
3  1111.3  Mark
5  1111.4  Mark

首先是必须读取字符串等值,然后测试模式数字“。” 最后一位:

df = pd.read_csv("file.csv", dtype={'Value':str})
df = df[df['Value'].str.match('\d+\.\d{1}$')]

另一个不转换为字符串的想法,但可能会出现浮点精度问题,例如1111.100000000094894

s = df['Value'] * 10
df = df[s.eq(s.astype(int))]
print (df)
    Value  Name
0  1111.1  Mark
1  1111.2  Mark
3  1111.3  Mark
5  1111.4  Mark

排除在点和结尾之间没有 1 作为单个数字或在点和结尾之间没有 0 的任何行。

df[(df['Value'].astype(str).str.contains('(?<=\.)[^0]$|(?<=\.)[1]$'))]



   Value  Name
0  1111.1  Mark
1  1111.2  Mark
3  1111.3  Mark
5  1111.4  Mark

根据您的评论让我们尝试

        Value   Name
0  1111.100000   Mark
1  1111.200000   Mark
2  1111.230000   Mark
3  1111.300000   Mark
4  1111.346000   Mark
5  1111.400000   Mark
6  1111.100099  Added

输出

    Value  Name
0  1111.1  Mark
1  1111.2  Mark
3  1111.3  Mark
5  1111.4  Mark

尝试这个:

 df["value"] = df["value"].apply(lambda x: x - x % 0.1)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM