检查 Pandas DataFrame 列是否包含浮点精度内的重复项

Check whether Pandas DataFrame column contains duplicates within floating point precision

提问人:kulpojke 提问时间:12/24/2021 最后编辑:kulpojke 更新时间:12/24/2021 访问量:132

问:

我有一个 xyz 点的数据帧 ,有 4 列 、 、 和 ,都包含浮点数。该数据帧是通过连接另外两个数据帧和 而创建的。dfxyzClassificationdf1df2

中的所有点都是 中的点的子集,但两个数据帧在不同的软件中经历了不同的处理。中的所有点的分类均为 14。其中没有一个点是 14 类的。因此,在 df 中,有些点本质上是 xyz 重复项(这些 xyz 重复项的数量是 ),其中一半是 14 类。我想找到这些重复项并丢弃那些不是 14 类的重复项。df2df1df2df1len(df2)

我说这些行本质上是 xyz 重复项,因为在之前的处理过程中,许多行都引入了浮点误差。

>>> # make example data,
>>> # small differences introduced on 2nd data
>>> x1 = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
>>> x2 = x1[:4] + np.array([0, 0, 3e-13, 0])

>>> y1 = np.array([10.0, 11.01, 12.0, 13.0, 14.0, 15.0, 16.0])
>>> y2 = y1[:4] + np.array([0, 0, 3e-13, 4e-13])

>>> z1 = np.array([10.0, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6])
>>> z2 = z1[:4] + np.array([0.0, 0.0, 3e-13, 4e-13])

>>> df1 = pd.DataFrame(columns=['x', 'y', 'z', 'Classification'])
>>> df1['x'] = x1
>>> df1['y'] = y1
>>> df1['z'] = z1
>>> df1['Classifcation'] = 0

>>> df2 = pd.DataFrame(columns=['x', 'y', 'z', 'Classification'])
>>> df2['x'] = x2
>>> df2['y'] = y2
>>> df2['z'] = z2
>>> df2['Classifcation'] = 14

>>> df1
     x      y     z  Classification
0  0.0  10.00  10.0               0
1  1.0  11.01  10.1               0
2  2.0  12.00  10.2               0
3  3.0  13.00  10.3               0
4  4.0  14.00  10.4               0
5  5.0  15.00  10.5               0
6  6.0  16.00  10.6               0

>>> df2
     x    y             z  Classification
0  0.0  0.0  3.000000e-13              14
1  1.0  1.0  1.000000e+00              14
2  2.0  2.0  2.000000e+00              14
3  3.0  3.0  3.000000e+00              14

>>> df = pd.concat ([df1, df2], axis=0)
>>> df
     x      y             z  Classification
0  0.0  10.00  1.000000e+01               0
1  1.0  11.01  1.010000e+01               0
2  2.0  12.00  1.020000e+01               0
3  3.0  13.00  1.030000e+01               0
4  4.0  14.00  1.040000e+01               0
5  5.0  15.00  1.050000e+01               0
6  6.0  16.00  1.060000e+01               0
0  0.0   0.00  3.000000e-13              14
1  1.0   1.00  1.000000e+00              14
2  2.0   2.00  2.000000e+00              14
3  3.0   3.00  3.000000e+00              14

最初我尝试过

>>> df0 = df.loc[~((df.duplicated(subset=['x', 'y', 'z'],
                          keep=False))
                 & (df.Classification != 14))]

>>> df0
     x      y     z  Classification
2  2.0  12.00  10.2               0
3  3.0  13.00  10.3               0
4  4.0  14.00  10.4               0
5  5.0  15.00  10.5               0
6  6.0  16.00  10.6               0
0  0.0  10.00  10.0              14
1  1.0  11.01  10.1              14
2  2.0  12.00  10.2              14
3  3.0  13.00  10.3              14

>>> len(df), len(df0)
(11, 9)

这丢弃了所有非 14 分类的精确重复项,但错过了由浮点错误创建的关闭(在 x、y 和 z 中)重复项。

我需要做一些事情,但行为是,因此在一定公差范围内的值将被视为重复。df.duplicatednumpy.isclose

谢谢

Python Pandas DataFrame 浮点 精度

评论

1赞 12/24/2021
请您展示一些数据帧的示例吗?这将使帮助:)变得容易得多
0赞 kulpojke 12/24/2021
我添加了一些示例数据。

答:

1赞 Yok Chirathivat 12/24/2021 #1

一种方法是在 concat 之前删除重复项,因为我知道您正在尝试删除 df1 中已经在 df2 中的行。这里的诀窍是使用 isin 并创建一个可以轻松比较两个数据帧的键,您可以使用字符串格式并设置小数点(下面的示例使用 5 点)。

df_1['key'] = df_1.apply(lambda row: f'{row["X"]:.5f}-{row["Y"]:.5f}-{row["Z"]:.5f}', axis=1)
df_2['key'] = df_2.apply(lambda row: f'{row["X"]:.5f}-{row["Y"]:.5f}-{row["Z"]:.5f}', axis=1)
df_1 = df_1[df_1['key'].isin(df_2['key'])==False]
combined = pd.concat([df_1, df_2])