如何在pandas中使用带有多索引的地图?

时间:2017-03-28 18:57:24

标签: python pandas multi-index

我有各种基因组位置的数据数据表。这些职位被表示为3元组('染色体' srand',位置),我已经变成了多指数。我的目标是查找有关每个位置的各种信息并将其添加到表中(例如基因名称等)我可以使用pybedtools来完成此操作。

df = pd.DataFrame(data={'A':range(1,8), 'B':range(1,8), 'C': range(1,8)},
 index=pd.MultiIndex.from_tuples([('chrom1', '-', 1234), ('chrom1', '+', 5678),
 ('chrom1', '+', 9876),  ('chrom2', '+', 13579), ('chrom2', '+', 8497), ('chrom2', '-', 98765),
 ('chrom2', '-', 76856)]))

df.index.rename(['chrom','strand','abs_pos'], inplace=True)

                       A  B  C
chrom  strand abs_pos         
chrom1 -      1234     1  1  1
       +      5678     2  2  2
              9876     3  3  3
chrom2 +      13579    4  4  4
              8497     5  5  5
       -      98765    6  6  6
              76856    7  7  7

我的问题是向具有多索引的数据框添加列。如果没有多指数,这似乎是直截了当的:pandas - add new column to dataframe from dictionary

我有一个查找信息的字典,其中包含与多索引相对应的3元组键。如何将此数据添加为新列?

gene_d = {('chrom1', '-', 1234) : 'geneA', ('chrom1', '+', 5678): 'geneB', 
    ('chrom1', '+', 9876): 'geneC', ('chrom2', '+', 13579): 'geneD',
    ('chrom2', '+', 8497): 'geneE', ('chrom2', '-', 98765): 'geneF', 
    ('chrom2', '-', 76856): 'geneG'}

我已经尝试了地图,但似乎无法弄清楚如何使用多索引来生成以下内容:

                                A  B  C
chrom  strand abs_pos gene
chrom1 -      1234    geneA     1  1  1
       +      5678    geneB     2  2  2
              9876    geneC     3  3  3
chrom2 +      13579   geneD     4  4  4
              8497    geneE     5  5  5
       -      98765   geneF     6  6  6
              76856   geneG     7  7  7

4 个答案:

答案 0 :(得分:7)

矢量化方法:

df['gene'] = df.index #you get the index as tuple
df['gene'] = df['gene'].map(gene_d)
df = df.set_index('gene', append=True)

结果df:

                                A   B   C
chrom   strand  abs_pos gene            
chrom1  -       1234    geneA   1   1   1
        +       5678    geneB   2   2   2
                9876    geneC   3   3   3
chrom2  +       13579   geneD   4   4   4
                8497    geneE   5   5   5
        -       98765   geneF   6   6   6
                76856   geneG   7   7   7

答案 1 :(得分:2)

将gene_d变为数据帧:

var s: UTF8String;
...
s := AnsiReplaceStr(s, '(y)', UTF8Encode(Emoji));

给它一个多索引:

df1 = pd.DataFrame.from_dict(gene_d, orient='index').rename(columns={0:'gene'})

与原始df:

连接
df1.index = pd.MultiIndex.from_tuples(df1.index)

做一些清理:

new_df = pd.concat([df, df1], axis=1).sort_values('A')

答案 2 :(得分:0)

循环很简单。注意,如果你要循环,那么dict可能不是一个合适的数据结构,可能只是一个元组列表?

In [14]: for k, v in gene_d.items():
    ...:     df.loc[k,'gene'] = v
    ...:

In [15]: df
Out[15]:
                       A  B  C   gene
chrom  strand abs_pos
chrom1 -      1234     1  1  1  geneA
       +      5678     2  2  2  geneB
              9876     3  3  3  geneC
chrom2 +      13579    4  4  4  geneD
              8497     5  5  5  geneE
       -      98765    6  6  6  geneF
              76856    7  7  7  geneG

In [16]:

答案 3 :(得分:0)

一种非矢量化方法,但对于真正为此苦苦挣扎的人可能有用。

在我的示例中,我有一个称为bb_df的df,它具有一个以[customer,months]为结构的多重索引,每个站点下面都有多个月份。多索引的结构类似于(级别= [level_1,level_2],标签= [level_1,level_2])。这样,您可以按以下列表理解顺序依次获取第2级级别的完整列表:

[bb_df.index.levels[1][x] for x in bb_df.index.labels[1]]

希望这对某人有帮助。