簡體   English   中英

python pandas - 通過自定義 ID 以多種方式比較兩個數據幀

[英]python pandas - compare two dataframes in multiple ways by custom ID

我需要檢查兩個不同日期的數據集中隨着時間的推移發生了什么變化:

之前的日期:

Date      ID        Value      Category  Subcategory
30-Nov    0001      100.00     A         A100
30-Nov    0002      200.00     B         B120
30-Nov    0003      300.00     C         C300
30-Nov    0004      450.00     D         D900
30-Nov    0005      500.00     D         D900

當前的日期:

Date      ID        Value      Category  Subcategory
31-Dec    0001      100.00     A         A100
31-Dec    0002      200.00     B         B101
31-Dec    0003      300.00     C         C300
31-Dec    0004      400.00     E         E900
31-Dec    0006      600.00     D         D900

現在我需要創建 4 個數據框:

  1. 價值變化:
Date      ID        Value      Category  Subcategory Prior Value
31-Dec    0004      400.00     E         E900        450.00
  1. 類別變化:
Date      ID        Value      Category  Subcategory Prior Category
31-Dec    0004      400.00     E         E900        D
  1. 子類別的變化,但前提是類別沒有變化:
Date      ID        Value      Category  Subcategory Prior Subcategory
31-Dec    0002      200.00     B         B101        B120
  1. 物品數量變化:
Date      ID        Value      Category  Subcategory
31-Dec    0006      600.00     D         D900
30-Nov    0005      500.00     D         D900

我想我應該首先運行人口檢查並排除那些中斷,所以我將只有兩個具有相同 ID 集的數據集。 我將按照此處的示例進行操作: 比較兩個數據幀並獲得差異

為了比較 1to1 值,我找到了 numpy 一段代碼,但它通過默認索引而不是 ID 進行比較,如何使用我的 ID 列作為記錄標識符來進行比較? 這將是一個大型數據集,我不能基於默認索引。

value_df = current_df
value_df['prior value'] = np.where(prior_df['Value'] == current_df['Value'], 'Match', prior_df['Value'])
value_df = value_df[value_df['prior value'] != 'Match']

對於多個條件,我必須逐步過濾掉它(首先過濾掉類別更改,然后過濾子類別更改)還是可以使用 AND 連接條件?

以下是創建數據框的代碼:

prior_data = {'Date': ['30-Nov','30-Nov','30-Nov','30-Nov', '30-Nov'],
          'ID': ['0001','0002','0003','0004', '0005'],
          'Value' : [100.00, 200.00, 300.00, 450.00, 500.00],
          'Category' : ['A','B','C','D','D'],
          'Subcategory' : ['A100','B120','C300','D900','D900']}


current_data = {'Date': ['31-Dec','31-Dec','31-Dec','31-Dec','31-Dec'],
          'ID': ['0001','0002','0003','0004', '0006'],
          'Value' : [100.00, 200.00, 300.00, 400.00, 600.00],
          'Category' : ['A','B','C','E','D'],
          'Subcategory' : ['A100','B101','C300','E900','D900']}

prior_df = pd.DataFrame(prior_data)
current_df = pd.DataFrame(current_data)

我不確定這是否是最快的解決方案,但這個問題似乎需要pd.merge 正如您所說,讓我們首先處理一個 dataframe 而不是另一個:

def get_only_left(df1, df2):
    left_merge = pd.merge(df1, df2, on='ID', suffixes=('', '_other'), how='left')
    added_columns = [c + '_other' for c in df1.columns if c != 'ID']
    mask = left_merge.loc[:, added_columns].isna().all(axis=1)
    return left_merge[mask].drop(added_columns, axis=1)

pd.concat([get_only_left(prior_df, current_df), get_only_left(current_df, prior_df)])

這給

     Date    ID  Value Category Subcategory
4  30-Nov  0005  500.0        D        D900
4  31-Dec  0006  600.0        D        D900

然后,讓我們處理正確更改的值。

columns = list(current_df.columns)
df = pd.merge(current_df, prior_df, on='ID', suffixes=('', '_prior'), how='inner')
mask = df['Value'] != df['Value_prior']
df[mask].loc[:, columns + ['Value_prior']]

這給

     Date    ID  Value Category Subcategory  Value_prior
3  31-Dec  0004  400.0        E        E900        450.0

然后類似地:

mask = df['Category'] != df['Category_prior']
df[mask].loc[:, columns + ['Category_prior']]

     Date    ID  Value Category Subcategory Category_prior
3  31-Dec  0004  400.0        E        E900              D

最后

import numpy as np
mask = np.logical_and(df['Category'] == df['Category_prior'], df['Subcategory'] != df['Subcategory_prior'])
df[mask].loc[:, columns + ['Subcategory_prior']]

     Date    ID  Value Category Subcategory Subcategory_prior
1  31-Dec  0002  200.0        B        B101              B120

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM