簡體   English   中英

如何從另一個pandas數據框中減去一行?

[英]How to subtract rows of one pandas data frame from another?

我想要做的操作類似於合並。 例如,通過inner合並,我們得到一個數據框,其中包含第一個和第二個數據框中存在的行。 通過outer合並,我們得到一個數據幀,該數據幀在第二個數據幀的第一個OR中出現。

我需要的是一個數據框,其中包含第一個數據框中存在的行而第二個數據框中不存在的行? 有一種快速而優雅的方式嗎?

怎么樣以下的東西?

print df1

    Team  Year  foo
0   Hawks  2001    5
1   Hawks  2004    4
2    Nets  1987    3
3    Nets  1988    6
4    Nets  2001    8
5    Nets  2000   10
6    Heat  2004    6
7  Pacers  2003   12

print df2

    Team  Year  foo
0  Pacers  2003   12
1    Heat  2004    6
2    Nets  1988    6

只要有一個非鍵的通常命名的列,你可以讓添加的on sufffex做工作(如果沒有非鍵的公共列,那么你可以創建一個暫時使用... df1['common'] = 1df2['common'] = 1 ):

new = df1.merge(df2,on=['Team','Year'],how='left')
print new[new.foo_y.isnull()]

     Team  Year  foo_x  foo_y
0  Hawks  2001      5    NaN
1  Hawks  2004      4    NaN
2   Nets  1987      3    NaN
4   Nets  2001      8    NaN
5   Nets  2000     10    NaN

或者您可以使用isin但您必須創建一個鍵:

df1['key'] = df1['Team'] + df1['Year'].astype(str)
df2['key'] = df1['Team'] + df2['Year'].astype(str)
print df1[~df1.key.isin(df2.key)]

     Team  Year  foo         key
0   Hawks  2001    5   Hawks2001
2    Nets  1987    3    Nets1987
4    Nets  2001    8    Nets2001
5    Nets  2000   10    Nets2000
6    Heat  2004    6    Heat2004
7  Pacers  2003   12  Pacers2003

考慮以下:

  1. df_one是第一個DataFrame
  2. df_two是第二個DataFrame

存在於第一個DataFrame中 而不存在於第二個DataFrame中

解決方案:按索引 df = df_one[~df_one.index.isin(df_two.index)]

index可以替換為您希望排除的必需 在上面的例子中,我使用了index作為兩個數據幀之間的引用

此外,您還可以使用更復雜的查詢使用boolean pandas.Series來解決上述問題。

如果非索引列包含具有NaN的單元格,則可能會遇到錯誤。

print df1

    Team   Year  foo
0   Hawks  2001    5
1   Hawks  2004    4
2    Nets  1987    3
3    Nets  1988    6
4    Nets  2001    8
5    Nets  2000   10
6    Heat  2004    6
7  Pacers  2003   12
8 Problem  2112  NaN


print df2

     Team  Year  foo
0  Pacers  2003   12
1    Heat  2004    6
2    Nets  1988    6
3 Problem  2112  NaN

new = df1.merge(df2,on=['Team','Year'],how='left')
print new[new.foo_y.isnull()]

     Team  Year  foo_x  foo_y
0   Hawks  2001      5    NaN
1   Hawks  2004      4    NaN
2    Nets  1987      3    NaN
4    Nets  2001      8    NaN
5    Nets  2000     10    NaN
6 Problem  2112    NaN    NaN

2112中的問題團隊在任何一個表中對foo都沒有價值。 因此,此處的左連接將錯誤地返回在兩個DataFrame中匹配的行,因為右側DataFrame中不存在該行。

解:

我所做的是向內部DataFrame添加一個唯一列,並為所有行設置一個值。 然后,當您加入時,您可以檢查該列是否為內部表的NaN,以便在外部表中查找唯一記錄。

df2['in_df2']='yes'

print df2

     Team  Year  foo  in_df2
0  Pacers  2003   12     yes
1    Heat  2004    6     yes
2    Nets  1988    6     yes
3 Problem  2112  NaN     yes


new = df1.merge(df2,on=['Team','Year'],how='left')
print new[new.in_df2.isnull()]

     Team  Year  foo_x  foo_y  in_df1  in_df2
0   Hawks  2001      5    NaN     yes     NaN
1   Hawks  2004      4    NaN     yes     NaN
2    Nets  1987      3    NaN     yes     NaN
4    Nets  2001      8    NaN     yes     NaN
5    Nets  2000     10    NaN     yes     NaN

NB。 問題行現在已正確過濾掉,因為它具有in_df2的值。

  Problem  2112    NaN    NaN     yes     yes

我建議在合並中使用參數'indicator'。 此外,如果'on'為None,則默認為兩個DataFrame中列的交集。

new = df1.merge(df2,how='left', indicator=True) # adds a new column '_merge'
new = new[(new['_merge']=='left_only')].copy() #rows only in df1 and not df2
new = new.drop(columns='_merge').copy()

    Team    Year    foo
0   Hawks   2001    5
1   Hawks   2004    4
2   Nets    1987    3
4   Nets    2001    8
5   Nets    2000    10

參考: https//pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.merge.html

indicator : boolean or string, default False

If True, adds a column to output DataFrame called “_merge” with information on the source of each row. 
Information column is Categorical-type and takes on a value of 
“left_only” for observations whose merge key only appears in ‘left’ DataFrame,
“right_only” for observations whose merge key only appears in ‘right’ DataFrame, 
and “both” if the observation’s merge key is found in both.

暫無
暫無

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

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