我有一个带有三个级别的multiindex的DataFrame,例如:
COL1 COL2 ...
CHROM POS LABEL
chr1 43 strA ... ... ...
strB ... ... ...
66 strC ... ... ...
strB ... ... ...
chr2 29 strD ... ... ...
... ... ... ... ... ...
和具有带有前两个DataFrame索引级别的multiindex的系列:
VAL
CHROM POS
chr1 43 v1
66 v2
chr2 29 v3
... ... ...
我想将一个包含Series的列添加到DataFrame中,为前两个级别匹配的每个索引重复值v1,v2 ...,如下所示:
COL1 COL2 NEW ...
CHROM POS LABEL
chr1 43 strA ... ... v1 ...
strB ... ... v1 ...
66 strC ... ... v2 ...
strB ... ... v2 ...
chr2 29 strD ... ... v3 ...
... ... ... ... ... ... ...
请注意,Series没有丢失的行,也就是说,DataFrame中的所有(CHROM,POS)也在系列中。 我有一个有效的解决方案:
pandas.Series(variant_db.index.map(lambda i: cov_per_sample[sample].loc[i[:2]]), index=variant_db.index)
但是,由于这个lambda,它对于大数据(数十万行)来说非常慢。 我尝试的速度要快得多:
df['NEW'] = s.reindex(df.index, method='ffill')
但是这样在df ['NEW']中有很多NaN,这不应该发生。使用method ='bfill'我在不同的位置获得NaN,但是在这两种情况下,某些行都会获得NaN,因此即使使用两者也行不通。
我想要一种方法来使用库函数来提高效率。 有人可以帮忙吗?
答案 0 :(得分: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']
答案 1 :(得分:0)
df1 = df1.reset_index().set_index(['CHROM', 'POS'])
df1['NEW'] = df2.VAL
答案 2 :(得分: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)