पांडा डेटा फ्रेम में सभी शून्य के साथ पंक्तियाँ ड्रॉप करें


104

मैं pandas dropna()कुछ या सभी कॉलम के साथ पंक्तियों को हटाने के लिए कार्यक्षमता का उपयोग कर सकता हूं NA। मान 0 वाले सभी स्तंभों के साथ पंक्तियों को छोड़ने के लिए एक समान कार्य है?

P   kt  b   tt  mky depth
1   0   0   0   0   0
2   0   0   0   0   0
3   0   0   0   0   0
4   0   0   0   0   0
5   1.1 3   4.5 2.3 9.0

इस उदाहरण में, हम डेटा फ्रेम से पहली 4 पंक्तियों को छोड़ना चाहते हैं।

धन्यवाद!


बस स्पष्ट करने के लिए, यह दो प्रश्न हैं। एक, सभी मानों के साथ स्तंभों को 0. के रूप में छोड़ने के लिए, लेकिन ड्रॉपना () के बराबर एक फ़ंक्शन के लिए, जो स्तंभों को किसी भी मान के साथ छोड़ देगा 0. के रूप में
कीमिया

जवाबों:


113

यह पता चला है कि यह सदिश रूप से व्यक्त किया जा सकता है:

> df = pd.DataFrame({'a':[0,0,1,1], 'b':[0,1,0,1]})
> df = df[(df.T != 0).any()]
> df
   a  b
1  0  1
2  1  0
3  1  1

6
अच्छा है, लेकिन मुझे लगता है कि आप के साथ निषेध से बच सकते हैंdf = df[(df.T != 0).any()]
Akavall

1
@ अवाकॉल बेहतर!
U2EF1

1
बस एक नोट: ओपी ड्रॉप करना चाहता था rows with all columns having value 0, लेकिन एक allविधि का अनुमान लगा सकता है ।
पाओलोचफ़

1
ये सभी उत्तर बताते हैं कि हम सभी शून्य के साथ पंक्तियों को कैसे छोड़ सकते हैं, हालांकि, मैं पहले कॉलम में 0 के साथ पंक्तियों को छोड़ना चाहता था। इस पोस्ट में सभी चर्चा और उत्तरों की मदद से, मैंने df.loc [df.iloc [:, 0]! = 0] करके ऐसा किया। बस साझा करना चाहता था क्योंकि यह समस्या इस प्रश्न से संबंधित है !!
हेमंत

2
पारगमन आवश्यक नहीं है, कोई भी () एक पैरामीटर के रूप में एक अक्ष ले सकता है। तो यह काम करता है: df = df [df.any (धुरी = 1)]
राहुल झा

130

एक लाइन। कोई संक्रमण की आवश्यकता:

df.loc[~(df==0).all(axis=1)]

और जो लोग समरूपता पसंद करते हैं, उनके लिए भी यह काम करता है ...

df.loc[(df!=0).any(axis=1)]

1
संक्षिप्तता के लिए (और, मेरी राय में, उद्देश्य की स्पष्टता) इसे और अकवाल की टिप्पणी को मिलाएं df.loc[(df != 0).any(1)]:। टीम वर्क!
डैन एलन

1
+1, 30% तेजी से जो स्थानांतरित करता है - 491 से 614 माइक्रोसेक, और मुझे axis=1स्पष्ट होने के लिए पसंद है ; मेरी राय में अधिक
अजगर

कुछ उल्लेख को .all और .any का उपयोग करने के बीच अंतर से बना होना चाहिए क्योंकि मूल प्रश्न ड्रॉपना के तुलनीयता का उल्लेख करता है। यदि आप शून्य वाले किसी भी कॉलम के साथ सभी पंक्तियों को छोड़ना चाहते हैं, तो आपको उपरोक्त उत्तर में .all और .any को उल्टा करना होगा। मुझे यह महसूस करने में थोड़ी देर लग गई कि मैं उस कार्यक्षमता की तलाश कर रहा था।
ज़क कीरन

यह मेरे लिए काम नहीं करता है, लेकिन मुझे ठीक वैसा ही लौटाता हैdf
रोबव

क्या इसका कोई 'इनकम' संस्करण है? मैं देख रहा हूं कि ओपी के अनुरोध के अनुसार पंक्तियों को ड्रॉप करने के लिए, यह करने की आवश्यकता होगी df = df.loc[(df!=0).all(axis=1)]और df = df.loc[(df!=0).any(axis=1)]किसी भी शून्य के साथ पंक्तियों को छोड़ने के लिए ड्रॉपना () के बराबर वास्तविक समकक्ष होगा।
कीमिया

20

मैं महीने में एक बार इस सवाल को देखता हूं और हमेशा टिप्पणियों से सबसे अच्छा जवाब खोदना पड़ता है:

df.loc[(df!=0).any(1)]

धन्यवाद दान एलन!


2
कोई खुदाई की आवश्यकता है। @ 8one6 ने 2014 में वापस अपने जवाब में इसे शामिल किया है, जो हिस्सा कहता है: "और उन लोगों के लिए जो समरूपता पसंद करते हैं ..."।
राहुल मुरमुरिया

14

शून्य को इसके साथ बदलें nanऔर फिर सभी प्रविष्टियों के साथ पंक्तियों को छोड़ दें nan। उसके बाद nanशून्य से बदलें ।

import numpy as np
df = df.replace(0, np.nan)
df = df.dropna(how='all', axis=0)
df = df.replace(np.nan, 0)

4
यदि आपके पास डेटा में पहले से मौजूद NaN-s है तो यह विफल हो जाएगा।
ओमरबी


7

विशेष रूप से बड़े डेटा सेटों के लिए इसे देखते हुए मुझे हल करने में मददगार जोड़े

df[(df.sum(axis=1) != 0)]       # 30% faster 
df[df.values.sum(axis=1) != 0]  # 3X faster 

@ U2EF1 से उदाहरण के साथ जारी:

In [88]: df = pd.DataFrame({'a':[0,0,1,1], 'b':[0,1,0,1]})

In [91]: %timeit df[(df.T != 0).any()]
1000 loops, best of 3: 686 µs per loop

In [92]: df[(df.sum(axis=1) != 0)]
Out[92]: 
   a  b
1  0  1
2  1  0
3  1  1

In [95]: %timeit df[(df.sum(axis=1) != 0)]
1000 loops, best of 3: 495 µs per loop

In [96]: %timeit df[df.values.sum(axis=1) != 0]
1000 loops, best of 3: 217 µs per loop

बड़े डेटासेट पर:

In [119]: bdf = pd.DataFrame(np.random.randint(0,2,size=(10000,4)))

In [120]: %timeit bdf[(bdf.T != 0).any()]
1000 loops, best of 3: 1.63 ms per loop

In [121]: %timeit bdf[(bdf.sum(axis=1) != 0)]
1000 loops, best of 3: 1.09 ms per loop

In [122]: %timeit bdf[bdf.values.sum(axis=1) != 0]
1000 loops, best of 3: 517 µs per loop

क्या बुरा काम होता है अगर आपकी पंक्ति में -1 और 1 है?
Rhys Ulerich

बेशक, अगर आप 0. पंक्तियों को जोड़ने के बराबर योग नहीं करेंगे, तो यहां इसके लिए एक त्वरित समाधान है, जो केवल थोड़ा धीमा है: df[~(df.values.prod(axis=1) == 0) | ~(df.values.sum(axis=1)==0)]
घड़ी की कल

ठेस () फ़ंक्शन कुछ भी हल नहीं करता है। यदि आपके पास पंक्ति में कोई 0 है जो वापस आ जाएगा। 0. यदि आपको इस तरह की पंक्ति को संभालना है: [-1, -0.5, 0, 0.5, 1], तो आपका कोई भी समाधान काम नहीं करेगा।
राहुल मुर्मुरिया

यहाँ एक सही संस्करण है जो स्वीकृत उत्तर की तुलना में तेजी से 3x काम करता है:bdf[np.square(bdf.values).sum(axis=1) != 0]
राहुल मुर्मुरिया

5
import pandas as pd

df = pd.DataFrame({'a' : [0,0,1], 'b' : [0,0,-1]})

temp = df.abs().sum(axis=1) == 0      
df = df.drop(temp)

परिणाम:

>>> df
   a  b
2  1 -1

1-कॉलम डेटाफ़्रेम के साथ मेरे लिए काम नहीं किया। मिलाValueError: labels [True ... ] not contained in matrix
अनफुन कैट

df = df.drop(temp)उपयोग के बजायdf = df.drop(df[temp].index)
डगलस फरेरा

3

यदि आप lambdaकिसी दिए गए पंक्ति में सभी मान हैं, तो यह जांचने के लिए आप एक त्वरित फ़ंक्शन का उपयोग कर सकते हैं 0। तब आप आवेदन करने के परिणाम का उपयोग कर सकते हैं, जो lambdaकेवल उन पंक्तियों को चुनने के लिए है जो उस स्थिति से मेल खाते हैं या मेल नहीं खाते हैं:

import pandas as pd
import numpy as np

np.random.seed(0)

df = pd.DataFrame(np.random.randn(5,3), 
                  index=['one', 'two', 'three', 'four', 'five'],
                  columns=list('abc'))

df.loc[['one', 'three']] = 0

print df
print df.loc[~df.apply(lambda row: (row==0).all(), axis=1)]

पैदावार:

              a         b         c
one    0.000000  0.000000  0.000000
two    2.240893  1.867558 -0.977278
three  0.000000  0.000000  0.000000
four   0.410599  0.144044  1.454274
five   0.761038  0.121675  0.443863

[5 rows x 3 columns]
             a         b         c
two   2.240893  1.867558 -0.977278
four  0.410599  0.144044  1.454274
five  0.761038  0.121675  0.443863

[3 rows x 3 columns]

1

एक अन्य विकल्प:

# Is there anything in this row non-zero?
# df != 0 --> which entries are non-zero? T/F
# (df != 0).any(axis=1) --> are there 'any' entries non-zero row-wise? T/F of rows that return true to this statement.
# df.loc[all_zero_mask,:] --> mask your rows to only show the rows which contained a non-zero entry.
# df.shape to confirm a subset.

all_zero_mask=(df != 0).any(axis=1) # Is there anything in this row non-zero?
df.loc[all_zero_mask,:].shape

0

मेरे लिए यह कोड: df.loc[(df!=0).any(axis=0)] काम नहीं किया। इसने सटीक डेटासेट लौटाए।

इसके बजाय, मैंने df.loc[:, (df!=0).any(axis=0)]डेटासेट में 0 मान वाले सभी कॉलमों का उपयोग और गिरा दिया

फ़ंक्शन ने .all()उन सभी स्तंभों को छोड़ दिया जिसमें मेरे डेटासेट में कोई भी शून्य मान हैं।



-2

किसी भी पंक्ति में मान 0 के साथ सभी कॉलम छोड़ने के लिए:

new_df = df[df.loc[:]!=0].dropna()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.