列の値に基づいてパンダのDataFrame行を削除する


511

次のDataFrameがあります。

             daysago  line_race rating        rw    wrating
 line_date                                                 
 2007-03-31       62         11     56  1.000000  56.000000
 2007-03-10       83         11     67  1.000000  67.000000
 2007-02-10      111          9     66  1.000000  66.000000
 2007-01-13      139         10     83  0.880678  73.096278
 2006-12-23      160         10     88  0.793033  69.786942
 2006-11-09      204          9     52  0.636655  33.106077
 2006-10-22      222          8     66  0.581946  38.408408
 2006-09-29      245          9     70  0.518825  36.317752
 2006-09-16      258         11     68  0.486226  33.063381
 2006-08-30      275          8     72  0.446667  32.160051
 2006-02-11      475          5     65  0.164591  10.698423
 2006-01-13      504          0     70  0.142409   9.968634
 2006-01-02      515          0     64  0.134800   8.627219
 2005-12-06      542          0     70  0.117803   8.246238
 2005-11-29      549          0     70  0.113758   7.963072
 2005-11-22      556          0     -1  0.109852  -0.109852
 2005-11-01      577          0     -1  0.098919  -0.098919
 2005-10-20      589          0     -1  0.093168  -0.093168
 2005-09-27      612          0     -1  0.083063  -0.083063
 2005-09-07      632          0     -1  0.075171  -0.075171
 2005-06-12      719          0     69  0.048690   3.359623
 2005-05-29      733          0     -1  0.045404  -0.045404
 2005-05-02      760          0     -1  0.039679  -0.039679
 2005-04-02      790          0     -1  0.034160  -0.034160
 2005-03-13      810          0     -1  0.030915  -0.030915
 2004-11-09      934          0     -1  0.016647  -0.016647

line_raceがに等しい行を削除する必要があり0ます。これを行う最も効率的な方法は何ですか?


回答:


878

私が正しく理解している場合、それは次のように単純でなければなりません:

df = df[df.line_race != 0]

16
df大きい場合、これはより多くのメモリを消費しますか?または、インプレースで実行できますか?
ziyuang

10
df200万行のa で実行しただけで、かなり高速でした。
Dror 2015

46
@vfxGer「列レース」のように列にスペースがある場合は、次のようにできますdf = df[df['line race'] != 0]
Paul

3
問題の値がその行のいずれかの列で見つかった場合に行全体を削除する場合、このコマンドをどのように変更しますか?
Alex

3
ありがとう!Fwiw、私にとってこれはそうでなければなりませんでしたdf=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
citynorman

181

しかし、将来のバイパスについてdf = df[df.line_race != 0]は、None/ missing値をフィルタリングしようとしても何も起こらないと言うこともできます。

動作します:

df = df[df.line_race != 0]

何もしません:

df = df[df.line_race != None]

動作します:

df = df[df.line_race.notnull()]

4
列名がわからない場合はどうすればよいですか?
Piyush S. Wanare

できますがdf = df[df.columns[2].notnull()]、何らかの方法で列にインデックスを付けることができるようにする必要があります。
erekalper

1
df = df[df.line_race != 0]行を削除しますが、インデックスをリセットしません。したがって、dfに別の行を追加すると、最後に追加されない場合があります。その操作の後にインデックスをリセットすることをお勧めします(df = df.reset_index(drop=True)
the_new_james

==開始するには、演算子でNoneと決して比較しないでください。stackoverflow.com/questions/3257919/...
ブラムVanroy

40

これを行う最善の方法は、ブール値のマスキングを使用することです。

In [56]: df
Out[56]:
     line_date  daysago  line_race  rating    raw  wrating
0   2007-03-31       62         11      56  1.000   56.000
1   2007-03-10       83         11      67  1.000   67.000
2   2007-02-10      111          9      66  1.000   66.000
3   2007-01-13      139         10      83  0.881   73.096
4   2006-12-23      160         10      88  0.793   69.787
5   2006-11-09      204          9      52  0.637   33.106
6   2006-10-22      222          8      66  0.582   38.408
7   2006-09-29      245          9      70  0.519   36.318
8   2006-09-16      258         11      68  0.486   33.063
9   2006-08-30      275          8      72  0.447   32.160
10  2006-02-11      475          5      65  0.165   10.698
11  2006-01-13      504          0      70  0.142    9.969
12  2006-01-02      515          0      64  0.135    8.627
13  2005-12-06      542          0      70  0.118    8.246
14  2005-11-29      549          0      70  0.114    7.963
15  2005-11-22      556          0      -1  0.110   -0.110
16  2005-11-01      577          0      -1  0.099   -0.099
17  2005-10-20      589          0      -1  0.093   -0.093
18  2005-09-27      612          0      -1  0.083   -0.083
19  2005-09-07      632          0      -1  0.075   -0.075
20  2005-06-12      719          0      69  0.049    3.360
21  2005-05-29      733          0      -1  0.045   -0.045
22  2005-05-02      760          0      -1  0.040   -0.040
23  2005-04-02      790          0      -1  0.034   -0.034
24  2005-03-13      810          0      -1  0.031   -0.031
25  2004-11-09      934          0      -1  0.017   -0.017

In [57]: df[df.line_race != 0]
Out[57]:
     line_date  daysago  line_race  rating    raw  wrating
0   2007-03-31       62         11      56  1.000   56.000
1   2007-03-10       83         11      67  1.000   67.000
2   2007-02-10      111          9      66  1.000   66.000
3   2007-01-13      139         10      83  0.881   73.096
4   2006-12-23      160         10      88  0.793   69.787
5   2006-11-09      204          9      52  0.637   33.106
6   2006-10-22      222          8      66  0.582   38.408
7   2006-09-29      245          9      70  0.519   36.318
8   2006-09-16      258         11      68  0.486   33.063
9   2006-08-30      275          8      72  0.447   32.160
10  2006-02-11      475          5      65  0.165   10.698

更新:パンダ0.13がリリースされたので、これを行う別の方法はdf.query('line_race != 0')です。


df.queryはとても便利に見えます!ありがとう!pandas.pydata.org/pandas-docs/version/0.13.1/generated/…–幻想的な2014
14:43

14
の良いアップデートquery。これにより、より豊富な選択基準が可能になります(たとえばdf.query('variable in var_list')、「var_list」が目的の値のリストであるようなセットのような操作)
philE

1
列名に名前にスペースが含まれている場合、これはどのように達成されますか?
iNoob、2015年

2
query列名にスペースが含まれている場合は、あまり役に立ちません。
Phillip Cloud

3
ヘッダーに次のようなスペースを含めることは避けますdf = df.rename(columns=lambda x: x.strip().replace(' ','_'))
Scientist1642

40

別のソリューションを追加するだけで、新しいパンダの評価者を使用している場合に特に便利です。他のソリューションは元のパンダを置き換え、評価者を失います

df.drop(df.loc[df['line_race']==0].index, inplace=True)

1
インデックスとインプレースを作成する目的は何ですか。誰か説明していただけますか?
heman123 2018年


.reset_index()誰かがインデックスアクセサーを使用してしまう場合も同様に必要になると思います
Ayush

17

列の複数の値に基づいて行を削除する場合は、以下を使用できます。

df[(df.line_race != 0) & (df.line_race != 10)]

の値が0と10のすべての行を削除しますline_race


あなたはすなわちをドロップしたい複数の値を持っていた場合は、これを行うには、より効率的な方法があり、drop = [0, 10]その後、のようなものdf[(df.line_race != drop)]
マイキー

14

上記の誰かdf.query('line_race != 0')があなたが問題に応じてはるかに速いものを使用できると言ったので、与えられた答えはそれでも正しいです。強くお勧めします。


DataFrame私のように長い変数名がある場合(そして、df例に使用されているものと比較して、皆さん全員が推測できると思います)は、一度書くだけでよいので、特に役立ちます。
ijoseph

9

以前の答えは私がやろうとしていることとほとんど同じですが、インデックスメソッドを使用する場合、別のインデックスメソッド.loc()を使用する必要はありません。これは、以下と同様の正確な方法で実行できます。

df.drop(df.index[df['line_race'] == 0], inplace = True)

1
大規模なデータセットやメモリに制約がある場合に適したソリューション。+1
davmor

3

それを行う別の方法。他の回答で言及されているコードよりもコードが少し複雑に見えるため、最も効率的な方法ではないかもしれませんが、同じことを行う別の方法です。

  df = df.drop(df[df['line_race']==0].index)

1

コードをコンパイルして実行しました。これは正確なコードです。自分で試すことができます。

data = pd.read_excel('file.xlsx')

列名に特殊文字またはスペースがある場合は''、所定のコードのように書き込むことができます。

data = data[data['expire/t'].notnull()]
print (date)

スペースや特殊文字を含まない単一の文字列列名のみの場合は、直接アクセスできます。

data = data[data.expire ! = 0]
print (date)

0

すべての列にDataFrameを展開する別の方法を追加するだけです。

for column in df.columns:
   df = df[df[column]!=0]

例:

def z_score(data,count):
   threshold=3
   for column in data.columns:
       mean = np.mean(data[column])
       std = np.std(data[column])
       for i in data[column]:
           zscore = (i-mean)/std
           if(np.abs(zscore)>threshold):
               count=count+1
               data = data[data[column]!=i]
   return data,count
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.