2017-02-24 4 views
4

を照合することによって、選択行は、私は、次の形式のパンダのデータフレームを作成する:パンダpython2.7で複数の他の列のエントリに列エントリ

 ID sps1 sps2 sps3 sps4 
0  1 1001 1001 1001 1001 
1  2 1111 0001 NaN 1101 
2  3 1000 NaN 1000 0101 

import pandas as pd 

df = pd.DataFrame({ 
'ID' : ['1','2','3'], 
'sps1' : ['1001', '1111', '1000'], 
'sps2' : ['1001','0001','NaN'], 
'sps3' : ['1001','NaN','1000'], 
'sps4' : ['1001','1101','0101'] 
}) 

したがって、のように見えます

各行には、固有のID(1,2,3など)を持つ異なる生物学的配列に関するデータが含まれています。各配列は4つの異なる種(sps1-4)に存在する。各シーケンスにおける4つの異なる特徴の存在(1)または不在(0)は、4桁のコードとして符号化される。一部の種には配列が欠けているため、NaNが記録されます。

このデータフレームから、私はSPS1のコードがすべて他の種のためのコードと一致しない行を選択します。

したがって、上記の例では、行0(コード1001はすべてのspで同じ)と行2(sps1のコード1000はsps3のものと一致します)ではなく、行1(sps1コード1111は一意です) 。

最終的に、同じ構造を持つ新しいデータフレームにこれらの選択された行を配置したいと思います。

私はパンダを初めて使用しています。私はSPS1とspsXのすべての組み合わせのために、このスタイルを続けることができた

matches = df.loc[((df['sps1'] != df['sps2']) & (df['sps1'] != df['sps3']))].index 
df_match = df.iloc[matches] 

が、私の完全な分析に私は12種の上向きに取り扱うので、このされます。これまでのところ私はこのようにそれを行うための方法を見つけることができました非常に効率的ではないタイピングの多くです。私はよりクリーンな方法がなければならないと思いますか?

+0

'1'、SPS1共有sps4 –

+0

申し訳あり、愚かなミスと同じコード( '1111)。今修正されました。 – Jack

答えて

3

あなたはパターンによって列を選択するfilterを使用し、sps1列は他のすべての列に等しいかどうかを確認するためにeqを使用することができますここでは、列単位で比較するためにaxis = rowsと指定します。これはサブセット化のために使用できる論理ベクトルを生成します。

df[(df.filter(regex = "^sps").eq(df.sps1, axis="rows")).sum(axis=1) == 1] 

# ID sps1 sps2 sps3 sps4 
#1 2 1111 0001  NaN 1101 
+1

これは賢明です。+1 – miradulo

+0

@Psidom FutureWarning:numpy equalは、今後オブジェクトIDをチェックしません。この比較はアイデンティティ(is is)によって提案されたものと同じ結果を返さず、変更されます。 result = op(x、y) – Jack

+0

@Psidomあなたのコードはデータフレームを生成しますが、動作するようですが、このエラーを報告します。私はエラーを理解していない。それって問題ですか? – Jack

0

あなたは正しく推測している:

df.loc[[df.iloc[i,1:].duplicated().sum() == 0 for i in df.index]] 

結果:

ID sps1 sps2 sps3 sps4 
1 2 1111 0001 NaN 1101 
1

Psidomは、すでにあなたはgreat answerで覆われているが、それのオフビットをピギーバック、あなたはに対して比較している列が含まれ、その後any()を使用することができませんでした各行を合計する必要はありません。

行で
df[~df.filter(regex="^sps(?!1$)\d+$").eq(df.sps1, axis='rows').any(1)] 
関連する問題