检查 Pandas DataFrame 列是否包含浮点精度内的重复项
Check whether Pandas DataFrame column contains duplicates within floating point precision
我有一个数据框,df
,包含 4 列的 xyz 点,x
、y
、z
和 Classification
,全部包含浮动。数据框是通过连接另外两个数据框 df1
和 df2
.
创建的
df2
中的所有点都是 df1
中的点的子集,但是这两个数据帧在不同的软件中进行了不同的处理。 df2
中的所有点都具有 14 的 class 化。df1
中的点中的 None 是 class 14。因此在 df 中有点本质上 xyz 重复项(这些 xyz 重复项的数量是 len(df2)
)其中一半是 class 14. 我想找到这些重复项并丢弃那些不是 class 14.
我说这些行基本上 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-classifed exact 重复项,但错过了由浮点数错误。
我需要做一些类似 df.duplicated
的事情,但具有 numpy.isclose
的行为,以便在一定公差范围内的值将被视为重复项。
谢谢
一种方法是删除 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])
我有一个数据框,df
,包含 4 列的 xyz 点,x
、y
、z
和 Classification
,全部包含浮动。数据框是通过连接另外两个数据框 df1
和 df2
.
df2
中的所有点都是 df1
中的点的子集,但是这两个数据帧在不同的软件中进行了不同的处理。 df2
中的所有点都具有 14 的 class 化。df1
中的点中的 None 是 class 14。因此在 df 中有点本质上 xyz 重复项(这些 xyz 重复项的数量是 len(df2)
)其中一半是 class 14. 我想找到这些重复项并丢弃那些不是 class 14.
我说这些行基本上 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-classifed exact 重复项,但错过了由浮点数错误。
我需要做一些类似 df.duplicated
的事情,但具有 numpy.isclose
的行为,以便在一定公差范围内的值将被视为重复项。
谢谢
一种方法是删除 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])