[英]Comparing two dataframes columns
我有两个结构相同的数据框。
两者都必须采用以下格式:
file_name | country_name | country_code | .....
我想比较两者,并获得每列的相等百分比。
第二个数据框是测试 dataframe,它包含真实值。 一些值是 NaN,应该被忽略。 到目前为止,我已经成功地比较了两者,并得到了每列相等样本的总数,我的问题是将它们中的每一个除以相关样本的总数(第二个数据帧中没有 NaN),以一种“好的方式”。
例如:
df1
file_name | country_name
1 a
2 b
3 d
4 c
df2
file_name | country_name
1 a
2 b
3 nan
4 d
我预计此列的 output 为 66%,因为 3 个相关样本中有 2 个具有相同的值,而第 4 个是 nan,因此在计算中被忽略。
到目前为止我做了什么:
test_set = pd.read_excel(file_path)
test_set = test_set.astype(str)
a_set = pd.read_excel(file2_path)
a_set = a_set.astype(str)
merged_df = a_set.merge(test_set, on='file_name')
for field in fields:
if field == 'file_name':
continue
merged_df[field] = merged_df.apply(lambda x: 0 if x[field + '_y'] == 'nan' else 1 if x[field + '_x'].lower() == x[field + '_y'].lower() else 0, axis=1)
scores = merged_df.drop('file_name', axis=1).sum(axis=0)
这给了我这些(正确的)结果:
country_name 14
country_code 0
state_name 4
state_code 59
city 74
...
但是现在我想将它们中的每一个除以 test_set dataframe 中相应字段中不包含 NaN 的样本总数。我可以想到一些天真的方法来做到这一点,比如创建另一个列来保存不包含的数量每个列的 nan 值,但正在寻找一个漂亮的解决方案。
如果您不必合并,您可以使用:
import pandas as pd
import numpy as np
df1 = pd.DataFrame([
["1", "a"],
["2", np.NAN],
["3", "c"]
])
df2 = pd.DataFrame([
["1", "X"],
["100", "b"],
["3", "c"]
])
# expected:
# col 0: equal = 2, ratio: 2/3
# col 1: equal = 1, ratio: 1/2
df1 = df1.sort_index()
df2 = df2.sort_index()
def get_col_ratio(col):
colA = df1[col]
colB = df2[col]
colA_ = colA[~(colA.isna() | colB.isna())]
colB_ = colB[~(colA.isna() | colB.isna())]
return (colA_.str.lower() == colB_.str.lower()).sum() / len(colA_)
ratios = pd.DataFrame([[get_col_ratio(i) for i in df1.columns]], columns=df1.columns)
print(ratios)
或者,使用pd.merge
fields = df1.columns
merged = pd.merge(df1,df2, left_index=True, right_index=True)
def get_ratio(col):
cols = merged[[f"{col}_x",f"{col}_y"]]
cols = cols.dropna()
equal_rows = cols[cols.columns[0]].str.lower() == cols[cols.columns[1]].str.lower()
return equal_rows.sum() / len(cols)
ratios = pd.DataFrame([[get_ratio(i) for i in fields]], columns=fields)
ratios
由于您有唯一的文件名,我会使用所有矢量操作,利用索引 alignment:
# set the filename as index
df1b = df1.set_index('file_name')
# set the filename as index
df2b = df2.set_index('file_name')
# compare and divide by the number of non-NA
out = df1b.eq(df2b).sum().div(df2b.notna().sum())
Output:
country_name 0.666667
dtype: float64
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.