比较两个熊猫数据框

时间:2020-04-06 20:06:48

标签: python pandas dataframe

我正在尝试根据列的dtypes比较两个Pandas DataFrame。这些是方案:

  1. 如果dtype是'object',则第一个df中的每个数据条目都需要与第二个df中的相应条目完全匹配
  2. 如果dtype是'float'或'int',则它们必须彼此靠近

这是我到目前为止所拥有的:

for column in data_1.columns:
if df_1[column].dtypes == 'float' or  df_1[column].dtypes == 'int':
    comparison[column] = np.isclose(df_1[column], df_2[column])
else:
    comparison[column] = df_1[column].where(df_1[column].values == df_2[column].values).notna()

但是,在比较数据框中,我得到了很多误报,即,两列中的值相同时,我的比较数据框中有'False'。 为了测试这一点,我打印出了一些显示为假的数据点减法,结果为0,这是预期的:

print(np.isclose(df_1[df_1['id']=='72']['cad'], df_2[df_2['id']=='72']['cad'])) 
print(df_1[df_1['id']=='72']['cad'] - df_2[df_2['id']=='72']['cad'])

有人可以帮助我了解我在哪里搞砸吗?

编辑: 由于无法共享正在使用的数据,因此我整理了一个迷你示例,其中包括我正在执行的所有步骤并获得了预期的结果:

import numpy as np
import pandas as pd

df1 = pd.DataFrame(np.array([['a', ''], ['b', '2.0'], ['c', '3.01']]),columns=['id', 'value'])
df1['value'] = pd.to_numeric(df1['value'], errors='coerce')

df2 = pd.DataFrame(np.array([['a', ''], ['b', '2.0'], ['c', '3.0']]),columns=['id', 'value'])
df2['value'] = pd.to_numeric(df2['value'], errors='coerce')


comparison = pd.DataFrame(columns=['id', 'value'])
for column in df1.columns:
    if df1[column].dtypes == 'float' or  df1[column].dtypes == 'int':
        comparison[column] = np.isclose(df1[column], df2[column], equal_nan=True, atol=0.01, rtol=0.01)
    else:
        comparison[column] = df1[column].where(df1[column].values == df2[column].values).notna()
print(comparison.head())

经过进一步调查,我发现这是由于我排序所依据的原始数据集中缺少ID引起的。

1 个答案:

答案 0 :(得分:1)

我有一个简单的玩具示例,希望它也对您有用。我已将atol设置为0.1,以使b的第三个元素足够接近(真),而第二个元素应该相距太远(假)

df1 = pd.DataFrame({'a': list('abcd'), 'b': [1, 2, 3, 4]})
df2 = pd.DataFrame({'a': list('ab3d'), 'b': [1, 20.3, 3.05, 4]})
comparison = pd.DataFrame()

for col in df1.columns: 
    if df1[col].dtypes in ["int", "float"]:
        comparison[col] = np.isclose(df1[col], df2[col], atol=0.1)
   else: 
        comparison[col] = df1[col] == df2[col]
comparison 
       a      b
0   True   True
1   True  False
2  False   True
3   True   True