Pandalar'da yalnızca sıfır içeren bir sütunu nasıl silerim?


90

Şu anda değer olarak 1 ve 0 olan sütunlardan oluşan bir veri çerçevem ​​var, sütunlarda yinelemek ve sadece 0'lardan oluşanları silmek istiyorum. İşte şimdiye kadar denediklerim:

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)]

Hangi yıllar, analiz ettiğim çeşitli yıllara ait veri çerçevelerinin bir listesi, olanlar, içinde bir bulunan sütunlardan ve sıfırlar, tümü sıfırları içeren sütunların bir listesidir. Bir koşula göre sütunu silmenin daha iyi bir yolu var mı? Bazı nedenlerden dolayı, birler sütunlarının da sıfırlar listesinde olup olmadığını kontrol etmem ve tüm sıfır sütunlarının bir listesini elde etmek için sıfırlar listesinden kaldırmam gerekiyor.


Yanıtlar:


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

İşte nasıl çalıştığının bir dökümü:

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 != 0dfSıfır olmayan bir yerde True olan bir boole DataFrame oluşturur :

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)hangi sütunların sıfır olmayan girişlere sahip olduğunu gösteren bir boolean Serisi döndürür. (İşlem any0 ekseni boyunca - yani satırlar boyunca - değerleri tek bir boole değerinde toplar. Dolayısıyla sonuç, her sütun için bir boole değeridir.)

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

Ve df.locbu sütunları seçmek için kullanılabilir:

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

[2 rows x 2 columns]

Sıfır sütunları "silmek" için yeniden atayın df:

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

Bunu, içinde 0 veya 1 varsa ve bir hata veriyorsa bir sütunu düşürmeye çalışıyorum: df = df.loc [:, (df! = 0 & df! = 1) .any (axis = 0)]
morpheus

1
df.loc[:, (~df.isin([0,1])).any(axis=0)]aynı zamanda işe yarar.
unutbu

1
@IgorFobia: 0 olmadan birçok şey False-ish'dir. Örneğin, boş dizeler veya Yok veya NaN. Farkı göstermek için, if df = pd.DataFrame([[np.nan]*10]), sonra df.loc[:, df.any(axis=0)]boş bir DataFrame df.loc[:, (df != 0).any(axis=0)]döndürürken, 10 sütunlu bir DataFrame döndürür.
unutbu

5
Bir koşulun doğru olmadığını kontrol etmek yerine, bir koşulun doğru olup olmadığını kontrol etmemizin anlamanın daha kolay olduğuna inanıyorum. Bence (df == 0).all(axis=0)daha basit.
Ryszard Cetnarski

2
Arıza için teşekkürler. Her şeyi çok netleştirdi.
Regi Mathew

7

İşte kullanmanın alternatif bir yolu

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

Unutbu çözümüyle karşılaştırıldığında, bu yol açıkça daha yavaştır:

%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

Sıfır sütun adlarını elde etmenin daha anlamlı bir yolunu istiyorsanız, böylece bunları yazdırabilir / kaydedebilir ve adlarına göre yerine bırakabilirsiniz :

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)

Bazıları bozuldu:

# 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

Sütunlarınızda bazı NaN değerleri olması durumunda, hem 0 hem de NaN içeren sütunları kaldırmak istiyorsanız bu yaklaşımı kullanmak isteyebilirsiniz:

df.loc[:, df.sum() != 0]
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.