我有一个带有零值的头行和尾行的DataFrames集合。我想删除这些零值行,并保持它们之间的范围。
例如,给定此DataFrame:
x
0 0
1 0
2 1
3 0
4 3
5 1
6 0
7 0
我想要一个返回以下内容的函数:
x
2 1
3 0
4 3
5 1
请注意,第3行的零值没有丢失。我不想删除所有零,只删除头部和尾部。熊猫怎么办?
答案 0 :(得分:4)
使用:
df = df[df['x'].cumsum().mul(df['x'].iloc[::-1].cumsum()).ne(0)]
print (df)
x
2 1
3 0
4 3
5 1
说明:
获取列的cumsum
:
print (df['x'].cumsum())
0 0
1 0
2 1
3 1
4 4
5 5
6 5
7 5
Name: x, dtype: int64
再次反转列cumsum
:
print (df['x'].iloc[::-1].cumsum())
7 0
6 0
5 1
4 4
3 4
2 5
1 5
0 5
Name: x, dtype: int64
乘以Series.mul
:
print (df['x'].cumsum().mul(df['x'].iloc[::-1].cumsum()))
0 0
1 0
2 5
3 4
4 16
5 5
6 0
7 0
Name: x, dtype: int64
并检查是否等于(!=)
的{{3}} 0
:
print (df['x'].cumsum().mul(df['x'].iloc[::-1].cumsum()).ne(0))
0 False
1 False
2 True
3 True
4 True
5 True
6 False
7 False
Name: x, dtype: bool
最后按ne
过滤。
谢谢,@ Wen提供了另一种解决方案:
df[(df.x.eq(0).cumprod().eq(0))&(df.x[::-1].eq(0).cumprod().eq(0))]
答案 1 :(得分:3)
它也可能有用。 nonzero
将给出序列中非零元素的索引。访问元组的第一个和最后一个索引将产生预期的输出
import pandas as pd
df2=pd.DataFrame({'cols':[0,0,1,0,3,1,0,0]})
non_zero_index = df2.cols.nonzero()[0]
start, end = non_zero_index[0],non_zero_index[-1]
df2.loc[start:end]
cols
2 1
3 0
4 3
5 1
答案 2 :(得分:1)
对于具有很少零的大型数组,手动迭代将比布尔索引更有效。例如,通过带有next
和enumerate
的生成器表达式:
start = next(idx for idx, val in enumerate(df['x']) if val != 0)
end = -next(idx for idx, val in enumerate(df['x'].iloc[::-1]) if val != 0)
res = df['x'].iloc[start:end]
2 1
3 0
4 3
5 1
Name: x, dtype: int64
答案 3 :(得分:1)
我也要参加比赛。
正向求和,向后求和,如果等于零则取最小值。
df[np.minimum(df['x'].cumsum(), df['x'][::-1].cumsum()[::-1]).ne(0)]
输出:
x
2 1
3 0
4 3
5 1
答案 4 :(得分:0)
通过mad_启发
df.loc[df.x.mask(df.x==0).first_valid_index():df.x.mask(df.x==0).last_valid_index()]
Out[39]:
x
2 1
3 0
4 3
5 1
答案 5 :(得分:0)
d={'x':[0,0,1,2,1,0,0,4,4,0,0]}
df=pd.DataFrame(d)
删除尾零:
i=len(df)-1
x=df['x'][i]
while x==0:
i-=1
x=df['x'][i]
df=df[0:i+1]
删除头零:
while x==0:
del df['x'][i]
i-=1
x=df['x'][i]
df=df[i:]