我正在进行比较以确保df1中的帐号不会渗入df2中的其他帐号
我的目的是识别并输出每个df中包含任何“不需要的”匹配帐号的行坐标和值
df1和df2的一列包含如下帐号:
df1
Account Number
1234
5678
9101
1121
df2
Account Number
3141
5161
7181
9202
1222
1234
df2中的行数与df1不同,并且两个数据帧中的匹配值均为1234。考虑到每行计数从零开始,我的期望输出如下:
df1 Row 0 = df2 Row 5 as 1234
我是熊猫的新手,所以请原谅我的术语和方法。如果有更好更好的方法,我很乐意听取并实施。
我做了研究,我认为可能有一种使用合并或isin方法的方法吗?
任何想法将不胜感激=)
答案 0 :(得分:2)
您可以在该列上合并,然后使用输出在原始数据集中查找问题行
target_col = 'Account Number'
matching_account_nos = pd.merge(df1[[target_col]], df2[[target_col]], on='Account Number'), how='inner').values
# now use this to look up the rows in the original dataframes
problem_rows_df1 = df1[df1[target_col].isin(matching_account_nos)]
problem_rows_df2 = df2[df2[target_col].isin(matching_account_nos)]
合并将返回一个数据框,其中“帐户编号”相等。 .values
会将其变成一个numpy数组,您可以使用该数组查找原始数据框中需要哪些行?
答案 1 :(得分:1)
使用account number
作为结果DataFrame
中的索引并将行号存储在列中将是有意义的。最简单的解决方案是检查df1
和df2
中的每对索引,并将行号存储在df3
中,这将具有O(n ^ 2)复杂度。
编辑:看起来,您可以通过使用df1
过滤df2
和.isin
来提高性能,尽管我只是使用模拟数据进行了测试。仍然是O(n ^ 2),但是现在n是匹配帐户的数量,而不是总行数。
import pandas as pd
d1 = {'account': [1234, 5678, 9101, 1121]}
d2 = {'account': [3141, 5161, 7181, 9202, 1222, 1234]}
d3 = {'r1': [], 'r2': []}
df1 = pd.DataFrame(data = d1)
df2 = pd.DataFrame(data = d2)
df3 = pd.DataFrame(data = d3)
match1 = df1.account.isin(df2.account.values)
match2 = df2.account.isin(df1.account.values)
for r1 in df1[match1].index:
for r2 in df2[match2].index:
if df1.account[r1] == df2.account[r2]:
idx = df1.account[r1]
row = {'r1': r1, 'r2': r2}
df3.loc[idx] = row
编辑2:,使用此版本,我可以获得更好的性能,并且更简单:
match1 = df1.account.isin(df2.account.values)
for r1 in df1[match1].index:
idx = df1.account[r1]
r2 = df2[df2.account == idx].index[0]
row = {'r1': r1, 'r2': r2}
df3.loc[idx] = row
编辑3:如果df1
和df2
中的帐号不是唯一的,则不能使用account number
作为索引:
df3 = pd.DataFrame()
match1 = df1.account.isin(df2.account.values)
for r1 in df1[match1].index:
idx = df1.account[r1]
for r2 in df2[df2.account == idx].index:
row = {'account': idx, 'r1': r1, 'r2': r2}
df3 = df3.append(row, ignore_index=True)