2017-04-22 166 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()