pandalar: adları X ile başlayan tüm sütunları seçmenin en iyi yolu


110

Bir DataFrame'im var:

import pandas as pd
import numpy as np

df = pd.DataFrame({'foo.aa': [1, 2.1, np.nan, 4.7, 5.6, 6.8],
                   'foo.fighters': [0, 1, np.nan, 0, 0, 0],
                   'foo.bars': [0, 0, 0, 0, 0, 1],
                   'bar.baz': [5, 5, 6, 5, 5.6, 6.8],
                   'foo.fox': [2, 4, 1, 0, 0, 5],
                   'nas.foo': ['NA', 0, 1, 0, 0, 0],
                   'foo.manchu': ['NA', 0, 0, 0, 0, 0],})

İle başlayan sütunlarda 1 değerlerini seçmek istiyorum foo.. Bunu yapmanın daha iyi bir yolu var mı:

df2 = df[(df['foo.aa'] == 1)|
(df['foo.fighters'] == 1)|
(df['foo.bars'] == 1)|
(df['foo.fox'] == 1)|
(df['foo.manchu'] == 1)
]

Şunun gibi bir şey yazmaya benzer bir şey:

df2= df[df.STARTS_WITH_FOO == 1]

Cevap şu şekilde bir DataFrame yazdırmalıdır:

   bar.baz  foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu nas.foo
0      5.0     1.0         0             0        2         NA      NA
1      5.0     2.1         0             1        4          0       0
2      6.0     NaN         0           NaN        1          0       1
5      6.8     6.8         1             0        5          0       0

[4 rows x 7 columns]

Yanıtlar:


163

Sütunlarınızı oluşturmak için bir liste kavrama gerçekleştirin:

In [28]:

filter_col = [col for col in df if col.startswith('foo')]
filter_col
Out[28]:
['foo.aa', 'foo.bars', 'foo.fighters', 'foo.fox', 'foo.manchu']
In [29]:

df[filter_col]
Out[29]:
   foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu
0     1.0         0             0        2         NA
1     2.1         0             1        4          0
2     NaN         0           NaN        1          0
3     4.7         0             0        0          0
4     5.6         0             0        0          0
5     6.8         1             0        5          0

Diğer bir yöntem, sütunlardan bir dizi oluşturmak ve vektörleştirilmiş str yöntemini kullanmaktır startswith:

In [33]:

df[df.columns[pd.Series(df.columns).str.startswith('foo')]]
Out[33]:
   foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu
0     1.0         0             0        2         NA
1     2.1         0             1        4          0
2     NaN         0           NaN        1          0
3     4.7         0             0        0          0
4     5.6         0             0        0          0
5     6.8         1             0        5          0

İstediğinizi elde etmek için, ==1kriterlerinizi karşılamayan değerleri filtrelemek için aşağıdakileri eklemeniz gerekir :

In [36]:

df[df[df.columns[pd.Series(df.columns).str.startswith('foo')]]==1]
Out[36]:
   bar.baz  foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu nas.foo
0      NaN       1       NaN           NaN      NaN        NaN     NaN
1      NaN     NaN       NaN             1      NaN        NaN     NaN
2      NaN     NaN       NaN           NaN        1        NaN     NaN
3      NaN     NaN       NaN           NaN      NaN        NaN     NaN
4      NaN     NaN       NaN           NaN      NaN        NaN     NaN
5      NaN     NaN         1           NaN      NaN        NaN     NaN

DÜZENLE

Tamam, ne istediğinizi gördükten sonra, kıvrımlı cevap şudur:

In [72]:

df.loc[df[df[df.columns[pd.Series(df.columns).str.startswith('foo')]] == 1].dropna(how='all', axis=0).index]
Out[72]:
   bar.baz  foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu nas.foo
0      5.0     1.0         0             0        2         NA      NA
1      5.0     2.1         0             1        4          0       0
2      6.0     NaN         0           NaN        1          0       1
5      6.8     6.8         1             0        5          0       0

68

Pandaların dizinleri dizge işlemlerini desteklediğine göre, muhtemelen 'foo' ile başlayan sütunları seçmenin en basit ve en iyi yolu şudur:

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

Alternatif olarak, sütun (veya satır) etiketlerini ile filtreleyebilirsiniz df.filter(). Şununla başlayan adlarla eşleşecek bir normal ifade belirtmek için foo.:

>>> df.filter(regex=r'^foo\.', axis=1)
   foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu
0     1.0         0             0        2         NA
1     2.1         0             1        4          0
2     NaN         0           NaN        1          0
3     4.7         0             0        0          0
4     5.6         0             0        0          0
5     6.8         1             0        5          0

Yalnızca gerekli satırları (a içeren 1) ve sütunları locseçmek için, aşağıdakileri kullanarak sütunları filter(veya başka bir yöntemi) ve satırları seçerek kullanabilirsiniz any:

>>> df.loc[(df == 1).any(axis=1), df.filter(regex=r'^foo\.', axis=1).columns]
   foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu
0     1.0         0             0        2         NA
1     2.1         0             1        4          0
2     NaN         0           NaN        1          0
5     6.8         1             0        5          0

Buraya geldiğim cevap bu, soru başlığıyla uyuşuyor. OP'nin aslında istediği şey daha çok "Yalnızca x ile başlayan sütunlara dayalı bir filtreyle satır seçmenin en iyi yolu" gibiydi.
34'te scign

8

En basit yol, str'yi doğrudan sütun adlarında kullanmaktır, buna gerek yoktur. pd.Series

df.loc[:,df.columns.str.startswith("foo")]



2

@ EdChum'un cevabına göre aşağıdaki çözümü deneyebilirsiniz:

df[df.columns[pd.Series(df.columns).str.contains("foo")]]

Bu, seçmek istediğiniz tüm sütunların başlamaması durumunda gerçekten yardımcı olacaktır foo. Bu yöntem, alt dizeyi içeren tüm sütunları seçer foove bir sütunun adının herhangi bir noktasına yerleştirilebilir.

Özünde, .startswith()ile değiştirdim .contains().


1

"Foo" ile başlayan sütunları filtrelemek için burada normal ifadeyi deneyebilirsiniz.

df.filter(regex='^foo*')

Sütununuzda foo dizesine ihtiyacınız varsa, o zaman

df.filter(regex='foo*')

uygun olacaktır.

Bir sonraki adım için kullanabilirsiniz

df[df.filter(regex='^foo*').values==1]

'foo *' sütununun değerlerinden birinin 1 olduğu satırları filtrelemek için.


0

Çözümüm. Performansta daha yavaş olabilir:

a = pd.concat(df[df[c] == 1] for c in df.columns if c.startswith('foo'))
a.sort_index()


   bar.baz  foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu nas.foo
0      5.0     1.0         0             0        2         NA      NA
1      5.0     2.1         0             1        4          0       0
2      6.0     NaN         0           NaN        1          0       1
5      6.8     6.8         1             0        5          0       0

0

İstenen girişlerin seçilmesi için başka bir seçenek kullanmaktır map:

df.loc[(df == 1).any(axis=1), df.columns.map(lambda x: x.startswith('foo'))]

bu size a içeren satırlar için tüm sütunları verir 1:

   foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu
0     1.0         0             0        2         NA
1     2.1         0             1        4          0
2     NaN         0           NaN        1          0
5     6.8         1             0        5          0

Satır seçimi yapılır

(df == 1).any(axis=1)

@ ajcr'nin cevabında olduğu gibi:

0     True
1     True
2     True
3    False
4    False
5     True
dtype: bool

bu satır anlamına gelir 3ve 4a içermez 1ve seçilmez.

Sütunların seçimi böyle Boole indeksleme kullanılarak yapılır:

df.columns.map(lambda x: x.startswith('foo'))

Yukarıdaki örnekte bu,

array([False,  True,  True,  True,  True,  True, False], dtype=bool)

Bir sütun ile başlamıyorsa Yani, foo, Falsedöndürülür ve sütun nedenle seçilmemiştir.

Yalnızca 1, istediğiniz çıktının önerdiği gibi , içeren tüm satırları döndürmek istiyorsanız,

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

hangi döner

   bar.baz  foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu nas.foo
0      5.0     1.0         0             0        2         NA      NA
1      5.0     2.1         0             1        4          0       0
2      6.0     NaN         0           NaN        1          0       1
5      6.8     6.8         1             0        5          0       0

0

Benim durumumda bir önek listesine ihtiyacım vardı

colsToScale=["production", "test", "development"]
dc[dc.columns[dc.columns.str.startswith(tuple(colsToScale))]]
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.