मैं ऐसे कॉलम को कैसे हटाऊं जिसमें पंडों में केवल शून्य हो?


90

मेरे पास वर्तमान में 1 और 0 के मान के साथ स्तंभों से युक्त एक डेटाफ्रेम है, मैं स्तंभों के माध्यम से पुनरावृति करना चाहता हूं और केवल 0 से बने लोगों को हटा देना चाहता हूं। यहाँ मैंने जो अभी तक कोशिश की है:

ones = []
zeros = []
for year in years:
    for i in range(0,599):
        if year[str(i)].values.any() == 1:
            ones.append(i)
        if year[str(i)].values.all() == 0:
            zeros.append(i)
    for j in ones:
        if j in zeros:
            zeros.remove(j)
    for q in zeros:
        del year[str(q)]

जिन वर्षों में मैं विश्लेषण कर रहा हूं विभिन्न वर्षों के लिए डेटाफ्रेम की एक सूची है, उनमें से एक में कॉलम एक होते हैं और शून्य सभी कॉलम वाले कॉलम की एक सूची है। क्या किसी शर्त के आधार पर किसी कॉलम को हटाने का बेहतर तरीका है? किसी कारण से मुझे यह जांचना होगा कि क्या सभी कॉलम शून्य सूची में हैं और सभी शून्य स्तंभों की सूची प्राप्त करने के लिए उन्हें शून्य सूची से हटा दें।


जवाबों:


220
df.loc[:, (df != 0).any(axis=0)]

यहाँ एक ब्रेक डाउन है कि यह कैसे काम करता है:

In [74]: import pandas as pd

In [75]: df = pd.DataFrame([[1,0,0,0], [0,0,1,0]])

In [76]: df
Out[76]: 
   0  1  2  3
0  1  0  0  0
1  0  0  1  0

[2 rows x 4 columns]

df != 0एक बूलियन बनाता है DataFrame जो सच है जहां dfगैर-शून्य है:

In [77]: df != 0
Out[77]: 
       0      1      2      3
0   True  False  False  False
1  False  False   True  False

[2 rows x 4 columns]

(df != 0).any(axis=0)एक बूलियन श्रृंखला देता है जो दर्शाता है कि किन कॉलमों में गैर-एंटेरो प्रविष्टियां हैं ( anyऑपरेशन 0-अक्ष के साथ मूल्यों को जोड़ता है - यानी पंक्तियों के साथ - एक एकल बूलियन मूल्य में। इसलिए परिणाम प्रत्येक कॉलम के लिए एक बूलियन मान है।)

In [78]: (df != 0).any(axis=0)
Out[78]: 
0     True
1    False
2     True
3    False
dtype: bool

और df.locउन कॉलम को चुनने के लिए इस्तेमाल किया जा सकता है:

In [79]: df.loc[:, (df != 0).any(axis=0)]
Out[79]: 
   0  2
0  1  0
1  0  1

[2 rows x 2 columns]

शून्य-स्तंभों को "हटाने" के लिए, फिर से असाइन करें df:

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

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

1
df.loc[:, (~df.isin([0,1])).any(axis=0)]काम भी करेगा।
अनटु न् यू

1
@IgorFobia: लॉट की चीजें बिना फेल-ईश के हैं। उदाहरण के लिए, खाली तार या कोई नहीं या NaN। अंतर प्रदर्शित करने के लिए, यदि df = pd.DataFrame([[np.nan]*10]), फिर df.loc[:, df.any(axis=0)]एक खाली डेटाफ़्रेम लौटाता है, जबकि df.loc[:, (df != 0).any(axis=0)]10 कॉलम के साथ एक डेटाफ़्रेम लौटाता है।
unutbu

5
मेरा मानना ​​है कि यह समझना आसान है कि क्या हम किसी शर्त के लिए जाँच करते हैं, यह जाँचने के बजाय कि अगर हालत सही नहीं है तो कभी संतुष्ट नहीं होना चाहिए। मुझे लगता (df == 0).all(axis=0)है कि अधिक सीधा है।
रिसजार्ड सेटनार्स्की

2
टूटने के लिए धन्यवाद। इसने चीजों को बहुत स्पष्ट कर दिया।
रेगी मैथ्यू

7

यहाँ उपयोग करने का एक वैकल्पिक तरीका है

df.replace(0,np.nan).dropna(axis=1,how="all")

अनटुब के समाधान की तुलना में, यह तरीका स्पष्ट रूप से धीमा है:

%timeit df.loc[:, (df != 0).any(axis=0)]
652 µs ± 5.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df.replace(0,np.nan).dropna(axis=1,how="all")
1.75 ms ± 9.49 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

0

यदि आप शून्य-स्तंभ नामों को प्राप्त करने का अधिक स्पष्ट तरीका चाहते हैं, तो आप उन्हें अपने नाम से मुद्रित / लॉग इन कर सकते हैं, और उन्हें इन-प्लेस कर सकते हैं :

zero_cols = [ col for col, is_zero in ((df == 0).sum() == df.shape[0]).items() if is_zero ]
df.drop(zero_cols, axis=1, inplace=True)

कुछ टूट गए:

# a pandas Series with {col: is_zero} items
# is_zero is True when the number of zero items in that column == num_all_rows
(df == 0).sum() == df.shape[0])

# a list comprehension of zero_col_names is built from the_series
[ col for col, is_zero in the_series.items() if is_zero ]

0

यदि आपके कॉलम में कुछ NaN मान हैं, तो आप इस दृष्टिकोण का उपयोग करना चाह सकते हैं यदि आप उन स्तंभों को हटाना चाहते हैं जिनमें 0 और Na दोनों हैं:

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