2017-04-22 112 views
1

的問題如下:Python的大熊貓有條件更新

  • 的列有:姓,名,部門(諮詢或銷售,分別簡寫成C和S),員工ID和薪水。在這個例子中,薪金列沒有任何功能;這只是強調實際上有很多其他列。
  • 某些名字重複的部門之間。
  • 不知道這是否會有所幫助,但first_name + last_name + id形式的每一行的唯一標識符。我不得不使用它,因爲它是最短的唯一標識符標識在以前的重複去除場景大部分副本(見行1和2)。我可以走一步,用更加列串連這個標識符,但是這只是不是一個非常優雅的解決方案。

初始數據框如下:

first_name | last_name | id | dept | salary 
------------------------------------------- 
sarah  | jones  | C1 | C | 60000 
sarah  | jones  | C2 | C | 55000 
robert  | jones  | C3 | C | 50000 
alice  | clarke | C4 | C | 40000 
alice  | clarke | S1 | S | 40000 
thomas  | roberts | S2 | S | 45000 

我想刪除第4行(這是與諮詢部門相關的alice clarke行),並保持5行,但保留諮詢部門ID。也就是說,我應該有:

first_name | last_name | id | dept | salary 
------------------------------------------- 
sarah  | jones  | C1 | C | 60000 
sarah  | jones  | C2 | C | 55000 
robert  | jones  | C3 | C | 50000 
alice  | clarke | C4 | S | 40000 
thomas  | roberts | S2 | S | 45000 

(IRL:我有兩個數據源,D1和D2 D2數據是更高質量的,而是由D1中使用的ID被更廣泛的認可,像的ISO標準。因此,無論D1和D2碰巧給我同一行,我想使用D1 ID和D2的實際數據。)

實際問題比這個MVWE稍微複雜一些重複刪除情況)。我試過切碎這些問題的一些我以前上的重複去除或有條件壓倒一切的價值觀的問題,但一直沒能成功地解決了整個事情,主要是因爲我已經無法正常模塊化的問題。 This有條件更新行的問題可能會有所幫助。

+1

澄清:你是否希望保持S重複,但與C ID? – DyZ

+1

還有一個困惑點:假設你也有愛麗絲克萊克C5。現在,愛麗絲克萊克S1是C4還是C5的複製品? – DyZ

+1

一個例子雖然非常有用,但它基本上是必需的,但並不能代替實際說出你想要應用的標準。 – DSM

回答

1

每有些評論你的例子是在細節上有點短,但如果我理解正確的話,你基本上有兩個數據幀,並想保持一個從一些信息,並從另一其他信息。假設你真正開始有兩個dataframes,並且在合併的掌控當中,combine_first()應該做的伎倆:

csv = io.StringIO(u''' 
first last  id dept salary 
sarah jones C1 C  60 
sarah jones C2 C  55 
robert jones C3 C  50 
alice clarke C4 C  40 
thomas roberts S2 S  45 
''') 

df = pd.read_csv(csv, delim_whitespace = True) 

csv2 = io.StringIO(u''' 
first last  id dept salary 
alice clarke S1 S  43 
''') 

df2 = pd.read_csv(csv2, delim_whitespace = True) 
df2.drop('id', axis = 1) 

print df2.set_index(['first','last']).combine_first(df.set_index(['first','last'])).reset_index() 

輸出:

first last dept id salary 
0 alice clarke S  C4 43.0 
1 robert jones C  C3 50.0 
2 sarah jones C  C1 60.0 
3 sarah jones C  C2 55.0 
4 thomas roberts S  S2 45.0 

當然,你可以進行排序,您看合適的那一點。

0

如果起始點是所提供的初始數據幀,並考慮到只有兩個dept類型,可以groupby名稱,然後apply選擇/交換功能:

# using initial data frame provided, copied to clipboard 
df = pd.read_clipboard().drop(0, 0).drop(['|','|.1','|.2','|.3'], 1) 

def choose_data(data, chosen_field, chosen_value, swap_field): 
    if len(data[chosen_field].unique()) > 1: 
     chosen = data[data[chosen_field]==chosen_value] 
     chosen[swap_field] = data.ix[data[chosen_field]!=chosen_value, swap_field].values 
     return chosen 
    return data 

(df.groupby(['first_name','last_name'], as_index=False) 
    .apply(choose_data, 
      chosen_field='dept', 
      chosen_value='S', 
      swap_field='id') 
    .reset_index(drop=True) 
    .sort_values('id') 
) 

收率:

first_name last_name id dept salary 
0  sarah  jones C1 C 60000.0 
1  sarah  jones C2 C 55000.0 
2  robert  jones C3 C 50000.0 
3  alice clarke C4 S 40000.0 
4  thomas roberts S2 S 45000.0 

注意,reset_index()sort_values()基本上都是化妝品,一切真的有必要爲groupby()apply()