簡體   English   中英

在數據框之間的列上設置差異

[英]Set differences on columns between dataframes

注意:此問題的靈感來自另一篇文章中討論的思想: Pandas中的DataFrame代數

假設我有兩個數據框AB ,對於某些列col_name ,它們的值是:

A[col_name]   |  B[col_name]  
--------------| ------------
1             |  3
2             |  4
3             |  5
4             |  6

我想基於col_name計算AB之間的設置差異。 該操作的結果應為:

AA[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.

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