[英]Creating a 'differences' result set of two pandas dataframes with grouped key columns
[英]Set differences on columns between dataframes
注意:此問題的靈感來自另一篇文章中討論的思想: Pandas中的DataFrame代數
假設我有兩個數據框A
和B
,對於某些列col_name
,它們的值是:
A[col_name] | B[col_name]
--------------| ------------
1 | 3
2 | 4
3 | 5
4 | 6
我想基於col_name
計算A
和B
之間的設置差異。 該操作的結果應為:
A
中A[col_name]
與B[col_name]
中的任何條目都不匹配的行。
以下是以上示例的結果(也顯示了A
其他列):
A[col_name] | A[other_column_1] | A[other_column_2]
------------+-------------------|------------------
1 | 'foo' | 'xyz' ....
2 | 'bar' | 'abc'
請記住, A[col_name]
和B[col_name]
中的某些條目可能具有值np.NaN
。 我想將這些條目視為未定義但不同 ,即,設置差異應返回它們 。
如何在熊貓中做到這一點? (在多個列上概括出差異也將是很大的)
一種方法是使用Series isin
方法:
In [11]: df1 = pd.DataFrame([[1, 'foo'], [2, 'bar'], [3, 'meh'], [4, 'baz']], columns = ['A', 'B'])
In [12]: df2 = pd.DataFrame([[3, 'a'], [4, 'b']], columns = ['A', 'C'])
現在,您可以檢查df1['A']
中的每個項目是否在df2['A']
:
In [13]: df1['A'].isin(df2['A'])
Out[13]:
0 False
1 False
2 True
3 True
Name: A, dtype: bool
In [14]: df1[~df1['A'].isin(df2['A'])] # not in df2['A']
Out[14]:
A B
0 1 foo
1 2 bar
我認為這也滿足了NaN的需求:
In [21]: df1 = pd.DataFrame([[1, 'foo'], [np.nan, 'bar'], [3, 'meh'], [np.nan, 'baz']], columns = ['A', 'B'])
In [22]: df2 = pd.DataFrame([[3], [np.nan]], columns = ['A'])
In [23]: df1[~df1['A'].isin(df2['A'])]
Out[23]:
A B
0 1.0 foo
1 NaN bar
3 NaN baz
注意:對於大框架,可能有必要將這些列作為索引(以執行在另一個問題中討論的聯接 )。
在兩個或多個列上合並的一種方法是使用虛擬列:
In [31]: df1 = pd.DataFrame([[1, 'foo'], [np.nan, 'bar'], [4, 'meh'], [np.nan, 'eurgh']], columns = ['A', 'B'])
In [32]: df2 = pd.DataFrame([[np.nan, 'bar'], [4, 'meh']], columns = ['A', 'B'])
In [33]: cols = ['A', 'B']
In [34]: df2['dummy'] = df2[cols].isnull().any(1) # rows with NaNs in cols will be True
In [35]: merged = df1.merge(df2[cols + ['dummy']], how='left')
In [36]: merged
Out[36]:
A B dummy
0 1 foo NaN
1 NaN bar True
2 4 meh False
3 NaN eurgh NaN
布爾值存在於df2中,True在合並列之一中具有NaN。 按照您的規范,我們應該刪除那些為False的那些:
In [37]: merged.loc[merged.dummy != False, df1.columns]
Out[37]:
A B
0 1 foo
1 NaN bar
3 NaN eurgh
不雅。
這是一個也不理想的選項,因為它會將NaN
值預先映射到其他值( 0
),以便可以將它們用作索引:
def left_difference(L, R, L_on, R_on, NULL_VALUE):
L[L_on] = L[L_on].fillna(NULL_VALUE)
L.set_index(L_on, inplace=True)
R[R_on] = R[R_on].fillna(NULL_VALUE)
R.set_index(R_on, inplace=True)
# MultiIndex difference:
diff = L.ix[L.index - R.index]
diff = diff.reset_index()
return diff
為了使這項工作peroperly, NULL_VALUE
不應使用值L_on
也不R_on
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.