Xóa hàng DataFrame trong Pandas dựa trên giá trị cột


511

Tôi có DataFrame sau:

             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

Tôi cần phải loại bỏ các hàng line_racebằng 0. Cách hiệu quả nhất để làm điều này là gì?


Câu trả lời:


878

Nếu tôi hiểu chính xác, nó sẽ đơn giản như:

df = df[df.line_race != 0]

16
Điều này sẽ tốn thêm bộ nhớ nếu dflớn? Hoặc, tôi có thể làm điều đó tại chỗ?
ziyuang

10
Chỉ cần chạy nó trên một hàng dfvới 2 triệu và nó đã đi khá nhanh.
Dror

46
@vfxGer nếu có một khoảng trắng trong cột, như 'đường đua', thì bạn chỉ có thể làmdf = df[df['line race'] != 0]
Paul

3
Làm thế nào chúng ta sẽ sửa đổi lệnh này nếu chúng ta muốn xóa toàn bộ hàng nếu giá trị trong câu hỏi được tìm thấy trong bất kỳ cột nào trong hàng đó?
Alex

3
Cảm ơn! Fwiw, đối với tôi điều này phải làdf=df[~df['DATE'].isin(['2015-10-30.1', '2015-11-30.1', '2015-12-31.1'])]
citynorman

181

Nhưng đối với bất kỳ người bỏ qua nào trong tương lai, bạn có thể đề cập rằng df = df[df.line_race != 0]không làm gì khi cố gắng lọcNone / thiếu các giá trị.

Làm việc:

df = df[df.line_race != 0]

Không làm gì cả:

df = df[df.line_race != None]

Làm việc:

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

4
Làm thế nào để làm điều đó nếu chúng ta không biết tên cột?
Piyush S. Wanare

Có thể làm df = df[df.columns[2].notnull()], nhưng bằng cách này hay cách khác bạn cần để có thể lập chỉ mục cột bằng cách nào đó.
erekalper

1
df = df[df.line_race != 0]giảm các hàng nhưng cũng không thiết lập lại chỉ mục. Vì vậy, khi bạn thêm một hàng khác trong df, nó có thể không thêm vào cuối. Tôi khuyên bạn nên đặt lại chỉ mục sau thao tác đó ( df = df.reset_index(drop=True))
the_new_james

Bạn không bao giờ nên so sánh với Không có ==nhà điều hành để bắt đầu. stackoverflow.com/questions/3257919/ cường
Bram Vanroy

40

Cách tốt nhất để làm điều này là với mặt nạ boolean:

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

CẬP NHẬT: Bây giờ gấu trúc 0.13 đã ra, một cách khác để làm điều này là df.query('line_race != 0').


df.query trông rất hữu ích! Cảm ơn! pandas.pydata.org/pandas-docs/version/0.13.1/generated/ trên
fantabolous

14
Cập nhật tốt cho query. Nó cho phép nhiều tiêu chí lựa chọn phong phú hơn (ví dụ: các hoạt động giống như tập df.query('variable in var_list')hợp như trong đó 'var_list' là danh sách các giá trị mong muốn)
philE

1
làm thế nào điều này sẽ đạt được nếu tên cột có một khoảng trắng trong tên?
iNoob

2
querysẽ không hữu ích nếu tên cột có khoảng trắng trong đó.
Đám mây Phillip

3
Tôi sẽ tránh có khoảng trống trong các tiêu đề bằng thứ gì đó như thế nàydf = df.rename(columns=lambda x: x.strip().replace(' ','_'))
Nhà khoa

40

chỉ cần thêm giải pháp khác, đặc biệt hữu ích nếu bạn đang sử dụng người đánh giá gấu trúc mới, các giải pháp khác sẽ thay thế gấu trúc ban đầu và mất người đánh giá

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

1
mục đích của việc viết chỉ mục và inplace là gì. Bất cứ ai có thể giải thích?
heman123


Tôi nghĩ rằng chúng ta cũng cần phải làm .reset_index()như vậy nếu ai đó kết thúc bằng cách sử dụng bộ truy cập chỉ mục
Ayush

17

Nếu bạn muốn xóa các hàng dựa trên nhiều giá trị của cột, bạn có thể sử dụng:

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

Để thả tất cả các hàng có giá trị 0 và 10 cho line_race.


Có cách nào hiệu quả hơn để làm điều này không nếu bạn có nhiều giá trị bạn muốn giảm, drop = [0, 10]và sau đó là một cái gì đó nhưdf[(df.line_race != drop)]
mikey

14

Câu trả lời được đưa ra là không chính xác vì một người nào đó ở trên cho biết bạn có thể sử dụng df.query('line_race != 0')tùy theo vấn đề của bạn nhanh hơn nhiều. Rất khuyến khích.


Đặc biệt hữu ích nếu bạn có DataFrametên biến dài như tôi (và, tôi muốn đoán, mọi người so dfvới ví dụ được sử dụng), vì bạn chỉ phải viết một lần.
ijoseph

9

Mặc dù câu trả lời previou gần như tương tự với những gì tôi sẽ làm, nhưng sử dụng phương thức chỉ mục không yêu cầu sử dụng phương thức lập chỉ mục khác .loc (). Nó có thể được thực hiện theo cách tương tự nhưng chính xác như

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

1
Giải pháp tại chỗ tốt hơn cho các bộ dữ liệu lớn hoặc bộ nhớ bị hạn chế. +1
davmor

3

Một cách khác để làm điều đó. Có thể không phải là cách hiệu quả nhất vì mã có vẻ phức tạp hơn một chút so với mã được đề cập trong các câu trả lời khác, nhưng vẫn là cách khác để làm điều tương tự.

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

0

Chỉ cần thêm một cách khác cho DataFrame được mở rộng trên tất cả các cột:

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

Thí dụ:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.