1. ホーム
  2. python

[解決済み] 重複するインデックスを持つpandasの行を削除する

2022-03-14 16:02:16

質問

重複するインデックス値を持つ行を削除するには?

下の気象データフレームでは、科学者が観測結果をさかのぼって修正することがあります。間違った行を編集するのではなく、重複する行をファイルの末尾に追加することによって修正します。

ウェブから自動化された気象データを読んでいる(観測は5分ごとに行われ、各測候所ごとに月別ファイルにまとめられている)。ファイルをパースすると、DataFrameは次のようになります。

                      Sta  Precip1hr  Precip5min  Temp  DewPnt  WindSpd  WindDir  AtmPress
Date                                                                                      
2001-01-01 00:00:00  KPDX          0           0     4       3        0        0     30.31
2001-01-01 00:05:00  KPDX          0           0     4       3        0        0     30.30
2001-01-01 00:10:00  KPDX          0           0     4       3        4       80     30.30
2001-01-01 00:15:00  KPDX          0           0     3       2        5       90     30.30
2001-01-01 00:20:00  KPDX          0           0     3       2       10      110     30.28

重複する場合の例です。

import pandas 
import datetime

startdate = datetime.datetime(2001, 1, 1, 0, 0)
enddate = datetime.datetime(2001, 1, 1, 5, 0)
index = pandas.DatetimeIndex(start=startdate, end=enddate, freq='H')
data1 = {'A' : range(6), 'B' : range(6)}
data2 = {'A' : [20, -30, 40], 'B' : [-50, 60, -70]}
df1 = pandas.DataFrame(data=data1, index=index)
df2 = pandas.DataFrame(data=data2, index=index[:3])
df3 = df2.append(df1)

df3
                       A   B
2001-01-01 00:00:00   20 -50
2001-01-01 01:00:00  -30  60
2001-01-01 02:00:00   40 -70
2001-01-01 03:00:00    3   3
2001-01-01 04:00:00    4   4
2001-01-01 05:00:00    5   5
2001-01-01 00:00:00    0   0
2001-01-01 01:00:00    1   1
2001-01-01 02:00:00    2   2

で、必要なのは df3 に最終的になるようにします。

                       A   B
2001-01-01 00:00:00    0   0
2001-01-01 01:00:00    1   1
2001-01-01 02:00:00    2   2
2001-01-01 03:00:00    3   3
2001-01-01 04:00:00    4   4
2001-01-01 05:00:00    5   5

と思ったのですが、行番号の列を追加することで ( df3['rownum'] = range(df3.shape[0]) のどのような値に対しても、最下段の行を選択できるようになります。 DatetimeIndex を理解するのに行き詰っています。 group_by または pivot (または???)ステートメントを使用して、それを動作させることができます。

どのように解決するのですか?

を使うことをお勧めします。 重複 メソッドを Pandas Index 自身に追加します。

df3 = df3[~df3.index.duplicated(keep='first')]

他のすべてのメソッドが動作している間 .drop_duplicates は、この例では圧倒的にパフォーマンスが低いです。さらに groupbyメソッド はパフォーマンスがわずかに劣りますが、私は重複したメソッドの方が読みやすいと思います。

提供されたサンプルデータを使って

>>> %timeit df3.reset_index().drop_duplicates(subset='index', keep='first').set_index('index')
1000 loops, best of 3: 1.54 ms per loop

>>> %timeit df3.groupby(df3.index).first()
1000 loops, best of 3: 580 µs per loop

>>> %timeit df3[~df3.index.duplicated(keep='first')]
1000 loops, best of 3: 307 µs per loop

なお、最後の要素は、keep 引数を 'last' .

また、このメソッドが MultiIndex で指定されたdf1を使用)。 Paulの例 ):

>>> %timeit df1.groupby(level=df1.index.names).last()
1000 loops, best of 3: 771 µs per loop

>>> %timeit df1[~df1.index.duplicated(keep='last')]
1000 loops, best of 3: 365 µs per loop