2014-11-04 84 views
0

我有具有三个电平的多指标一个数据帧,例如:大熊猫与数据帧重新索引

    COL1 COL2 ... 
CHROM POS LABEL     
chr1 43 strA ... ... ... 
      strB ... ... ... 
     66 strC ... ... ... 
      strB ... ... ... 
chr2 29 strD ... ... ... 
... ... ... ... ... ... 

,并用与所述数据帧索引的第2个电平的多指标一个系列:

  VAL 
CHROM POS  
chr1 43 v1 
     66 v2 
chr2 29 v3 
... ... ... 

我想用系列的数据框添加一列,重复值V1,V2 ......每一个指数,其前两个级别相匹配,就像这样:

    COL1 COL2 NEW ... 
CHROM POS LABEL     
chr1 43 strA ... ... v1 ... 
      strB ... ... v1 ... 
     66 strC ... ... v2 ... 
      strB ... ... v2 ... 
chr2 29 strD ... ... v3 ... 
... ... ... ... ... ... ... 

请注意,该系列没有缺失行,即DataFrame中的所有(CHROM,POS)也都位于Series中。 我有一个有效的解决方案:

pandas.Series(variant_db.index.map(lambda i: cov_per_sample[sample].loc[i[:2]]), index=variant_db.index) 

但是,因为拉姆达的,这是大数据(行的几十万)相当慢。 我试着用更快:

df['NEW'] = s.reindex(df.index, method='ffill') 

但这种方式也有在DF很多的NaN [“新”],这是不应该的。使用method ='bfill'我可以得到不同位置的NaN,但有些行在两种情况下都会得到NaN,所以即使使用两者也不行。

我想要一种方法来使用库函数,只为了提高效率。 任何人都可以帮忙吗?

回答

0

你可以尝试用你的大数据这个非常简单的解决方案的性能:

df1=pandas.DataFrame([ 
{'CHROM':'chr1','POS':43,'LABEL':'strA'}, 
{'CHROM':'chr1','POS':43,'LABEL':'strB'}, 
{'CHROM':'chr1','POS':66,'LABEL':'strC'}, 
{'CHROM':'chr1','POS':66,'LABEL':'strB'}, 
{'CHROM':'chr2','POS':29,'LABEL':'strD'}]) 

df2=pandas.DataFrame([ 
{'CHROM':'chr1','POS':43,'VAL':'v1'}, 
{'CHROM':'chr1','POS':66,'VAL':'v2'}, 
{'CHROM':'chr2','POS':29,'VAL':'v3'}]) 

for i,r in df2.iterrows(): 
    df1.ix[(df1['CHROM']==r['CHROM']) & (df1['POS']==r['POS']),'NEW']=r['VAL'] 

或者使用索引:

df1=pandas.DataFrame([ 
{'CHROM':'chr1','POS':43,'LABEL':'strA','COL':''}, 
{'CHROM':'chr1','POS':43,'LABEL':'strB','COL':''}, 
{'CHROM':'chr1','POS':66,'LABEL':'strC','COL':''}, 
{'CHROM':'chr1','POS':66,'LABEL':'strB','COL':''}, 
{'CHROM':'chr2','POS':29,'LABEL':'strD','COL':''}]).set_index(['CHROM','POS','LABEL']) 

df2=pandas.DataFrame([ 
{'CHROM':'chr1','POS':43,'VAL':'v1'}, 
{'CHROM':'chr1','POS':66,'VAL':'v2'}, 
{'CHROM':'chr2','POS':29,'VAL':'v3'}]).set_index(['CHROM','POS']) 

for i,r in df2.iterrows(): 
    df1.ix[(i[0],i[1]),'NEW']=r['VAL'] 
0

这是大熊猫的全部。使用您的优势指数。

df1 = df1.reset_index().set_index(['CHROM', 'POS']) 
df1['NEW'] = df2.VAL 
0

在阐述由@acushner提供的答案,这样的事情应该工作

midx = pd.MultiIndex.from_product(
    [["chr1","chr2"],[43,66,29],["strA","strB","strC"]], 
    names=["CHROM", "POS", "LABEL"] 
    ) 

df = pd.DataFrame(random.random([18,2]), index=midx) 

midx2 = pd.MultiIndex.from_product([["chr1","chr2"],[43,66,29]], 
            names=["CHROM", "POS"]) 
ser = pd.Series(random.random(6), index=midx2) 

df = df.reset_index().set_index(['CHROM', 'POS']) 
df[2] = ser 
df.set_index("LABEL", append=True, inplace=True)