Saat ini saya memiliki kerangka data yang terdiri dari kolom dengan nilai 1 dan 0, saya ingin mengulang melalui kolom dan menghapus yang hanya terdiri dari 0. Inilah yang telah saya coba sejauh ini:
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)]
Di mana tahun adalah daftar kerangka data untuk berbagai tahun yang saya analisis, yang terdiri dari kolom dengan satu di dalamnya dan nol adalah daftar kolom yang berisi semua nol. Apakah ada cara yang lebih baik untuk menghapus kolom berdasarkan kondisi? Untuk beberapa alasan saya harus memeriksa apakah kolom satu ada di daftar nol juga dan menghapusnya dari daftar nol untuk mendapatkan daftar semua kolom nol.
Jawaban:
df.loc[:, (df != 0).any(axis=0)]
Berikut ini rincian cara kerjanya:
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
membuat DataFrame boolean yang True di manadf
bukan nol: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)
mengembalikan Seri boolean yang menunjukkan kolom mana yang memiliki entri bukan nol. (any
Operasi menggabungkan nilai sepanjang sumbu 0 - yaitu di sepanjang baris - menjadi satu nilai boolean. Karenanya hasilnya adalah satu nilai boolean untuk setiap kolom.)In [78]: (df != 0).any(axis=0) Out[78]: 0 True 1 False 2 True 3 False dtype: bool
Dan
df.loc
dapat digunakan untuk memilih kolom tersebut:In [79]: df.loc[:, (df != 0).any(axis=0)] Out[79]: 0 2 0 1 0 1 0 1 [2 rows x 2 columns]
Untuk "menghapus" kolom nol, tetapkan kembali
df
:df = df.loc[:, (df != 0).any(axis=0)]
sumber
df.loc[:, (~df.isin([0,1])).any(axis=0)]
juga akan berhasil.df = pd.DataFrame([[np.nan]*10])
, makadf.loc[:, df.any(axis=0)]
kembalikan DataFrame kosong, sementaradf.loc[:, (df != 0).any(axis=0)]
kembalikan DataFrame dengan 10 kolom.(df == 0).all(axis=0)
lebih mudah.Berikut adalah cara alternatif yang bisa digunakan
df.replace(0,np.nan).dropna(axis=1,how="all")
Dibandingkan dengan solusi unutbu, cara ini jelas lebih lambat:
%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)
sumber
Jika Anda menginginkan cara yang lebih ekspresif untuk mendapatkan nama kolom nol sehingga Anda dapat mencetak / mencatatnya, dan meletakkannya, di tempat, dengan namanya :
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)
Beberapa rusak:
# 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 ]
sumber
Jika ada beberapa nilai NaN di kolom Anda, Anda mungkin ingin menggunakan pendekatan ini jika Anda ingin menghapus kolom yang memiliki 0 dan NaN:
df.loc[:, df.sum() != 0]
sumber