Adı Pandalar DataFrame'den belirli bir dize içeren sütunları bırak


107

Aşağıdaki sütun adlarına sahip bir panda veri çerçevem ​​var:

Result1, Test1, Result2, Test2, Result3, Test3, vb ...

Adında "Test" kelimesini içeren tüm sütunları kaldırmak istiyorum. Bu tür sütunların sayısı statik değildir, ancak önceki bir işleve bağlıdır.

Bunu nasıl yapabilirim?

Yanıtlar:


76
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
OP, kaldırma işleminin büyük / küçük harfe duyarlı olmaması gerektiğini belirtmedi.
Phillip Bulut

170

İşte bunu yapmanın bir yolu:

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

47
Veya doğrudan yerinde:df.drop(list(df.filter(regex = 'Test')), axis = 1, inplace = True)
Axel

7
Bu, kabul edilen cevaptan çok daha zarif bir çözümdür. Bunu nedenini göstermek için biraz daha parçalara ayırırdım, esas list(df.filter(regex='Test'))olarak satırın ne yaptığını daha iyi göstermek için çıkarırdım. df.filter(regex='Test').columnsListeden fazla dönüştürmeyi de tercih ederdim
Charles

3
Bu, kabul edilen cevaptan çok daha zarif.
deepelement

4
Bu cevabın "zarif" olduğunu söyleyen yorumların ne anlama geldiğini gerçekten merak ediyorum. Python kodunun ilk okunabilir olması gerektiğinde, ben bunu oldukça karmaşık buluyorum. Aynı zamanda ilk cevaptan iki kat daha yavaş. Ve regexanahtar likekelime daha yeterli göründüğünde anahtar kelimeyi kullanır .
Jacquot

2
Bu aslında insanların iddia ettiği kadar iyi bir cevap değil. Sorun filtertam o sütun olarak TÜM verilerin bir kopyasını döndürür yorulana istediğimi. Sadece bu sonucu drop(yine bir kopyasını döndürür) iletirseniz savurganlıktır ... daha iyi bir çözüm olacaktır str.startswith( burada bununla bir cevap ekledim ).
cs95

43

Daha Ucuz, Daha Hızlı ve Deyimsel: str.contains

Pandaların son sürümlerinde, dizin ve sütunlarda dize yöntemlerini kullanabilirsiniz. Burada str.startswithiyi bir uyum gibi görünüyor.

Belirli bir alt dizeyle başlayan tüm sütunları kaldırmak için:

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

Büyük / küçük harfe duyarsız eşleme için, str.containsbir SOL bağlantısıyla regex tabanlı eşleştirmeyi kullanabilirsiniz :

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

karışık türler bir olasılıksa, bunu da belirtin na=False.


15

'Filtre' kullanarak İSTEDİĞİNİZ sütunları filtreleyebilirsiniz.

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

Şimdi filtrele

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

Almak..

   result1  result34
0   2.0     NaN
1   NaN     10.0

4
En iyi cevap! Teşekkürler. Tersini nasıl filtrelersiniz? not like='result'
stallingOne

2
sonra şunu yapın: df = df.drop (df.filter (gibi = 'sonuç', eksen = 1) .columns, axis = 1)
Amir

14

Bu, tek bir satırda düzgünce yapılabilir:

df = df.drop(df.filter(regex='Test').columns, axis=1)

1
Benzer (ve daha hızlı):df.drop(df.filter(regex='Test').columns, axis=1, inplace=True)
Max Ghenis

9

DataFrame.selectYöntemi kullanın :

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

Ve operasyon bir sayının 'Test'i takip etmesi gerektiğini belirtmedi: Adı "Test" kelimesini içeren tüm sütunları kaldırmak istiyorum .
7

Bir sayının Test'i takip ettiği varsayımı tamamen mantıklıdır. Soruyu tekrar okuyun.
Phillip Bulut

2
şimdi görüyor: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Önceden hatırlayın .
ijoseph

5

Bu yöntem her şeyi yerinde yapar. Diğer cevapların çoğu kopyalar oluşturur ve o kadar verimli değildir:

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


2

Düşürmeyin. İstediğinizin tam tersini yakalayın.

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

1

bunu yapmanın en kısa yolu şudur:

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

Bu zaten bu yanıtın kapsamındaydı .
Gino Mempin

1
Yukarıdaki yorumda bağlantısı verilen cevap benzer olsa da aynı değildir. Aslında neredeyse tam tersi.
Makyen

0

Normal ifade içeren sütun adları listesi bırakılırken çözüm. Bu yaklaşımı tercih ediyorum çünkü açılan listeyi sık sık düzenliyorum. Açılır liste için negatif filtre normal ifadesi kullanır.

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.