pandas
drop_duplicates
関数は、データフレームの「一意化」に最適です。しかし、渡すキーワード引数の1つはtake_last=True
またはtake_last=False
ですが、列のサブセットにわたって重複するすべての行を削除したいのですが。これは可能ですか?
A B C
0 foo 0 A
1 foo 1 A
2 foo 1 B
3 bar 1 A
例として、列A
とC
に一致する行を削除したいので、これは行0と1を削除します。
これはパンダでは drop_duplicates とkeepパラメータを使うことでより簡単になりました。
import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.drop_duplicates(subset=['A', 'C'], keep=False)
ベンの答えに drop_duplicates を付け加えたいだけです。
keep
:{「最初」、「最後」、False}、デフォルトは「最初」
first:最初の出現を除いて重複を削除します。
last:最後の出現を除いて重複を削除します。
False:全ての重複を削除します。
そのため、keep
をFalseに設定すると、回答が得られます。
DataFrame.drop_duplicates(* args、** kwargs)重複行を削除したDataFrameを返します。オプションで特定の列のみを考慮します。
パラメーター:subset:列ラベルまたはラベルのシーケンス、オプション重複を識別するために特定の列のみを考慮します。デフォルトではすべての列を使用します。最初の出現last:最後の出現を除いて重複を削除します。 False:すべての重複を削除します。 take_last:廃止予定inplace:boolean、default False重複を正しい位置にドロップするか、コピーを返すかcols:kwargs onlyサブセットの引数のみ[廃止予定]
結果を別のデータセットに保存したい場合は、
df.drop_duplicates(keep=False)
または
df.drop_duplicates(keep=False, inplace=False)
同じデータセットを更新する必要がある場合:
df.drop_duplicates(keep=False, inplace=True)
上記の例では、SQLのDISTINCT *
と同様に、すべての重複を削除して1つ保持します。
groupby
とfilter
を使う
import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.groupby(["A", "C"]).filter(lambda df:df.shape[0] == 1)
実際には、0行目と1行目を削除するのに必要なのは(一致するAとCを含むすべての観測値が保持される)だけです。
In [335]:
df['AC']=df.A+df.C
In [336]:
print df.drop_duplicates('C', take_last=True) #this dataset is a special case, in general, one may need to first drop_duplicates by 'c' and then by 'a'.
A B C AC
2 foo 1 B fooB
3 bar 1 A barA
[2 rows x 4 columns]
しかし、私はあなたが本当に欲しいのはこれであると思います(一致したAとCを含む1つの観測は保持されます)。
In [337]:
print df.drop_duplicates('AC')
A B C AC
0 foo 0 A fooA
2 foo 1 B fooB
3 bar 1 A barA
[3 rows x 4 columns]
今ではそれははるかに明確になります。
In [352]:
DG=df.groupby(['A', 'C'])
print pd.concat([DG.get_group(item) for item, value in DG.groups.items() if len(value)==1])
A B C
2 foo 1 B
3 bar 1 A
[2 rows x 3 columns]