繁体   English   中英

比较2个不同长度的pandas dataframe得到值变化的列名

[英]Compare 2 pandas dataframe with different lengths and get the column name which has changed value

我有 2 个长度不等的数据帧。 有些记录可以同时存在,有些可能只存在于 1 dataframe 中。

data = [['1001', 4573, 'Test1'], ['1002', 4574, 'Test2'], ['1003', 4575, 'Test3']]
 
df1 = pd.DataFrame(data, columns = ['id', 'addressid','address'])

data = [['1001', 4573, 'Test1'], ['1002', 4574, 'Test22']]
 
df2 = pd.DataFrame(data, columns = ['id', 'addressid','address'])

我需要一种最佳方法来获取差异列名。 即,这里 id 1002 的地址从 Address2 更改为 Address22,所以我需要将列名返回为 output。

预期 Output:[地址]

这是一种不特定于列名的通用方法,假设多个列可能已更改,并且多个记录可能已更改:

请注意,我将“id”设置为索引,这样我就有了一些身份基础,可以在此基础上比较预期为同一实体的记录。

这不仅会打印为单个记录更改的单个列名,还会生成一个包含所有已更改记录的数据框/表,并显示已更改的列名(或名称列表)。

data = [['1001', 4573, 'Test1'], ['1002', 4574, 'Test2'], ['1003', 4575, 'Test3']]
df1 = pd.DataFrame(data, columns = ['id', 'addressid','address'])
data = [['1001', 4573, 'Test1'], ['1002', 4574, 'Test22']]
df2 = pd.DataFrame(data, columns = ['id', 'addressid','address'])


def getColChangedName(row):
    colsChanged = []
    for c in df1.columns.values:
        if row[c+"_diff"] == True:
            colsChanged.append(c)
    return ", ".join(colsChanged)


df1 = df1.set_index("id")
df2 = df2.set_index("id")

diffs = df1.merge(df2, left_index=True, right_index=True, suffixes=('_old', '_new'))

diff_cols = [c+"_diff" for c in df1.columns.values]

for c in df1.columns.values:
    diffs[c+"_diff"] = diffs[c+"_old"] != diffs[c+"_new"]
    
diffs["Record_Changed"] = diffs[diff_cols].sum(axis=1)/len(diff_cols) > 0


diffs = diffs[diffs["Record_Changed"] == 1]
diffs["Cols_Changed"] = diffs.apply(lambda row: getColChangedName(row), axis=1)

diffs.head()

产生的差异 DataFrame 在测试数据上看起来像这样:

在此处输入图像描述

而且,更简单地说,如果您只想更改每条记录的列列表:

print(diffs[["Cols_Changed"]])

     Cols_Changed
id               
1002      address

如果将id列设置为两个数据框的索引,则可以比较值(如合并):

# set id as index
df1 = df1.set_index('id')
df2 = df2.set_index('id')

# find inner join of index and columns
rows = df1.index.intersection(df2.index)
cols = df1.columns.intersection(df2.columns)

# get columns where at least one value is different
out = df2.loc[rows, cols].ne(df1.loc[rows, cols]).any() \
         .loc[lambda x: x].index.tolist()
print(out)

# Output
['address']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM