ड्रॉप कॉलम जिनके नाम में पांडा से एक विशिष्ट स्ट्रिंग है DataFrame


106

मेरे पास निम्नलिखित कॉलम नामों के साथ एक पांडा डेटाफ्रेम है:

Result1, Test1, Result2, Test2, Result3, Test3, आदि ...

मैं उन सभी स्तंभों को छोड़ना चाहता हूं जिनके नाम में "टेस्ट" शब्द है। ऐसे स्तंभों की संख्या स्थिर नहीं है, लेकिन पिछले फ़ंक्शन पर निर्भर करती है।

मैं उसे कैसे कर सकता हूँ?

जवाबों:


74
import pandas as pd

import numpy as np

array=np.random.random((2,4))

df=pd.DataFrame(array, columns=('Test1', 'toto', 'test2', 'riri'))

print df

      Test1      toto     test2      riri
0  0.923249  0.572528  0.845464  0.144891
1  0.020438  0.332540  0.144455  0.741412

cols = [c for c in df.columns if c.lower()[:4] != 'test']

df=df[cols]

print df
       toto      riri
0  0.572528  0.144891
1  0.332540  0.741412

2
ओपी ने यह निर्दिष्ट नहीं किया कि निष्कासन असंवेदनशील होना चाहिए।
फिलिप क्लाउड

163

यहाँ यह एक अच्छा तरीका है:

df = df[df.columns.drop(list(df.filter(regex='Test')))]

47
या सीधे जगह पर:df.drop(list(df.filter(regex = 'Test')), axis = 1, inplace = True)
Axel

7
स्वीकृत उत्तर की तुलना में यह बहुत अधिक सुरुचिपूर्ण समाधान है। मैं इसे थोड़ा और दिखाने के लिए तोड़ दूंगा कि क्यों, मुख्य रूप list(df.filter(regex='Test'))से यह दिखाने के लिए कि लाइन क्या कर रही है। मैं df.filter(regex='Test').columnsसूची रूपांतरण का भी विकल्प
चार्ल्स

2
यह एक तरह से स्वीकृत उत्तर की तुलना में अधिक सुरुचिपूर्ण है।
गहरीकरण

4
मैं वास्तव में आश्चर्यचकित हूं कि इस जवाब को कहने वाली टिप्पणियां "सुरुचिपूर्ण" हैं। मैं खुद इसे काफी अस्पष्ट मानता हूं, जब अजगर कोड को सबसे पहले पढ़ा जाना चाहिए। यह भी पहले उत्तर की तुलना में धीमी है। और यह regexकीवर्ड का उपयोग करता है जब likeकीवर्ड अधिक पर्याप्त लगता है।
जेकॉट

2
यह वास्तव में उतना अच्छा उत्तर नहीं है जितना लोग दावा करते हैं। इसके साथ समस्या filterयह है कि यह सभी डेटा की एक प्रति कॉलम के रूप में देता है जिसे आप छोड़ना चाहते हैं। यह बेकार है यदि आप केवल इस परिणाम को पास कर रहे हैं drop(जो फिर से एक प्रति लौटाता है) ... एक बेहतर समाधान होगा str.startswith(मैंने यहां एक उत्तर जोड़ा है)।
CS95

40

सस्ता, तेज़, और मुहावरेदार: str.contains

पांडा के हाल के संस्करणों में, आप अनुक्रमणिका और स्तंभों पर स्ट्रिंग विधियों का उपयोग कर सकते हैं। यहाँ, str.startswithएक अच्छा फिट की तरह लगता है।

दिए गए विकल्प के साथ शुरू होने वाले सभी स्तंभों को हटाने के लिए:

df.columns.str.startswith('Test')
# array([ True, False, False, False])

df.loc[:,~df.columns.str.startswith('Test')]

  toto test2 riri
0    x     x    x
1    x     x    x

केस-असंवेदनशील मिलान के लिए, आप str.containsSOL एंकर के साथ रेगेक्स-आधारित मिलान का उपयोग कर सकते हैं :

df.columns.str.contains('^test', case=False)
# array([ True, False,  True, False])

df.loc[:,~df.columns.str.contains('^test', case=False)] 

  toto riri
0    x    x
1    x    x

यदि मिश्रित प्रकार एक संभावना है, तो भी निर्दिष्ट करें na=False


15

आप उन स्तंभों को फ़िल्टर कर सकते हैं जिन्हें आप 'फ़िल्टर' का उपयोग करना चाहते हैं

import pandas as pd
import numpy as np

data2 = [{'test2': 1, 'result1': 2}, {'test': 5, 'result34': 10, 'c': 20}]

df = pd.DataFrame(data2)

df

    c   result1     result34    test    test2
0   NaN     2.0     NaN     NaN     1.0
1   20.0    NaN     10.0    5.0     NaN

अब छान लें

df.filter(like='result',axis=1)

प्राप्त..

   result1  result34
0   2.0     NaN
1   NaN     10.0

4
सबसे बढ़िया उत्तर! धन्यवाद। आप विपरीत कैसे फ़िल्टर करते हैं? not like='result'
स्टालिंगऑन

2
इसके बाद ऐसा करें: df = df.drop (df.filter (जैसे = 'परिणाम', अक्ष = 1)। कॉलम, अक्ष = 1)
अमीर


9

DataFrame.selectविधि का प्रयोग करें :

In [38]: df = DataFrame({'Test1': randn(10), 'Test2': randn(10), 'awesome': randn(10)})

In [39]: df.select(lambda x: not re.search('Test\d+', x), axis=1)
Out[39]:
   awesome
0    1.215
1    1.247
2    0.142
3    0.169
4    0.137
5   -0.971
6    0.736
7    0.214
8    0.111
9   -0.214

और ऑप ने यह निर्दिष्ट नहीं किया कि एक संख्या को 'टेस्ट' का पालन करना था: मैं उन सभी कॉलमों को छोड़ना चाहता हूं जिनके नाम में "टेस्ट" शब्द शामिल है
7stud

यह धारणा कि टेस्ट के बाद नंबर आता है, पूरी तरह से उचित है। सवाल फिर से।
फिलिप क्लाउड

2
अब देख रहे हैं:FutureWarning: 'select' is deprecated and will be removed in a future release. You can use .loc[labels.map(crit)] as a replacement
flutefreak7

import reपहले से याद रखें ।
जोजफ

5

यह तरीका सब कुछ करता है। अन्य कई उत्तर प्रतियाँ बनाते हैं और उतने कुशल नहीं हैं:

df.drop(df.columns[df.columns.str.contains('Test')], axis=1, inplace=True)


2

ड्रॉप मत करो। आप जो चाहते हैं उसके विपरीत पकड़ो।

df = df.filter(regex='^((?!badword).)*$').columns

1

सबसे छोटा तरीका है:

resdf = df.filter(like='Test',axis=1)

यह पहले से ही इस उत्तर द्वारा कवर किया गया था ।
गीनो मेम्पिन

1
जबकि उपरोक्त टिप्पणी में जुड़ा उत्तर समान है, यह समान नहीं है। वास्तव में, यह लगभग विपरीत है।
Makyen

0

Regex वाले स्तंभ नामों की सूची को छोड़ने पर समाधान। मैं इस दृष्टिकोण को पसंद करता हूं क्योंकि मैं अक्सर ड्रॉप सूची का संपादन कर रहा हूं। ड्रॉप सूची के लिए एक नकारात्मक फ़िल्टर रेगेक्स का उपयोग करता है।

drop_column_names = ['A','B.+','C.*']
drop_columns_regex = '^(?!(?:'+'|'.join(drop_column_names)+')$)'
print('Dropping columns:',', '.join([c for c in df.columns if re.search(drop_columns_regex,c)]))
df = df.filter(regex=drop_columns_regex,axis=1)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.