さまざまなゲノム位置のデータのデータテーブルがあります。位置は、私が多重指数に変えた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
私の問題は、多重指数を使用してデータフレームに列を追加することです。これは、マルチインデックスがなくても簡単に思えます: パンダ-辞書からデータフレームに新しい列を追加します
マルチインデックスに対応する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
ベクトル化されたアプローチ:
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
Gene_dをデータフレームにします。
df1 = pd.DataFrame.from_dict(gene_d, orient='index').rename(columns={0:'gene'})
それに多重指数を与える:
df1.index = pd.MultiIndex.from_tuples(df1.index)
元のdfと連結します。
new_df = pd.concat([df, df1], axis=1).sort_values('A')
クリーンアップを行います。
new_df.index.rename(['chrom','strand','abs_pos'], inplace=True)
new_df.set_index('gene', append=True)
new_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
ベクトル化されていないアプローチですが、これに本当に苦労している人にはおそらく役立つでしょう。
私の例では、bb_dfというdfがあります。これは、構造として[customer、months]を持つmultindexを持ち、各サイトの下に複数の月があります。 multindexは(levels = [level_1、level_2]、labels = [level_1、level_2])のように構成されています。そのため、次のリスト内包表記により、マッピング用にレベル2レベルの完全なリストを順番に取得できます。
[bb_df.index.levels[1][x] for x in bb_df.index.labels[1]]
これが誰かに役立つことを願っています。
ループを使用すると非常に簡単です。ループする場合は、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]: