我目前有一个由1列和0列作为值组成的数据帧,我想迭代列并删除仅由0组成的列。这是我到目前为止所尝试的内容:
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)]
在哪些年份是我正在分析的各年的数据框列表,其中包含列中包含一个的列,零是包含全零的列的列表。有没有更好的方法根据条件删除列?出于某种原因,我必须检查那些列是否也在零列表中,并从零列表中删除它们以获得所有零列的列表。
答案 0 :(得分:125)
df.loc[:, (df != 0).any(axis=0)]
以下是其工作原理的细分:
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
创建一个布尔数据框,其中df
非零,为True:
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)
返回一个布尔系列,指示哪些列具有非零条目。 (any
操作将沿0轴(即沿着行)的值聚合成一个布尔值。因此结果是每列的一个布尔值。)
In [78]: (df != 0).any(axis=0)
Out[78]:
0 True
1 False
2 True
3 False
dtype: bool
df.loc
可用于选择这些列:
In [79]: df.loc[:, (df != 0).any(axis=0)]
Out[79]:
0 2
0 1 0
1 0 1
[2 rows x 2 columns]
要“删除”零列,请重新分配df
:
df = df.loc[:, (df != 0).any(axis=0)]
答案 1 :(得分:0)
这是另一种使用方式
df.replace(0,np.nan).dropna(axis=1,how="all")
与unutbu的解决方案相比,这种方式显然更慢:
%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)
答案 2 :(得分:0)
如果您想以更更具表现力的方式获取零列名称,则可以打印/记录它们,并按其名称就地放置它们< / strong>:
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)
一些细分:
# 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 ]
答案 3 :(得分:0)
如果您的列中有一些 NaN 值,如果您想删除同时包含 0 和 NaN 的列,您可能需要使用这种方法:
df.loc[:, (df**2).sum() != 0]