获取Pandas Dataframe中包含非零列的前11行



我有一个pandas数据框架,如下所示。它有11列,其中只包含0和1,还有一列包含一些值,最后一列是标识符。我遇到了一个数据帧操作的问题。

我有一个情况我需要选择11行基于"值"列。(宽松约束)

但棘手的部分是,我必须以这样一种方式选择行,即在这11行中我不会得到任何零列。(硬约束).

所以我需要根据值选择前11行,并确保所有列都是非零的。每列中至少有一个值为1。

我正在寻找一些通用的解决方案,因为值列中的值会改变,但我的目标是根据值选择11行,并确保非零列是必须的。

任何想法?

a    b  c   d   e   f   g   h   i   j   k      values ID
0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.193744   1
0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.193744   2
0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.193744   3
0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 1.193744   4
0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.193744   5
0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.193744   6
0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.193744   7
0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.633150   8
0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.633150   9
0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.633150  10
0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.633150  11
0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.633150  12
0.0 0.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.033640  13
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.033640  14
0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.033640  15
1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.033640  16
0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.033640  17
1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.033640  18
0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.033640  19
1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.033640  20
0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.033640  21
0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.033640  22
0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.033640  23
0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.033640  24
1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.033640  25
1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 -0.279495 26
1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 -3.013531 27
1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 -3.013531 28

使用自定义函数-首先排序values,然后选择前11列byDataFrame.iloc,通过DataFrame.astype将浮点数转换为布尔值TrueFalses,因此如果DataFrame.rolling至少有一个1any填充,则可能测试每N块,因此N移位的行被NaNs填充,有必要将它们替换为0,转换为布尔值,如果所有行都有1DataFrame.all填充,则可能测试。

最后得到第一个True的索引,但如果所有False都存在,则返回Series.idxmax中的0,因此增加了if-else语句。

最后一个通过索引筛选top11:

def top_val_with_at_least_one_1(df, N):
df = df.sort_values('values', ascending=False, ignore_index=True, kind='mergesort')
m = (df.iloc[:, :11]
.astype(bool)
.rolling(N)
.apply(lambda x: x.any())
.fillna(0)
.astype(bool)
.all(axis=1))

if m.any():
idx = m.idxmax()
return df.loc[idx-N+1:idx]
else:
return pd.DataFrame()

print (top_val_with_at_least_one_1(df, 11))
a    b    c    d    e    f    g    h    i    j    k    values  ID
5   0.0  0.0  0.0  1.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  1.193744   6
6   0.0  0.0  0.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  1.193744   7
7   0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.633150   8
8   0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.633150   9
9   0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.633150  10
10  0.0  0.0  1.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.633150  11
11  0.0  0.0  1.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.633150  12
12  0.0  0.0  1.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.033640  13
13  0.0  0.0  1.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0  0.0  0.033640  14
14  0.0  1.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.0  0.033640  15
15  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  1.0  0.0  0.0  0.033640  16

尝试:

def get_desired_subset(top_rows):
for i in range(len(df)):
df_subset = df.loc[i:i+top_rows-1].reset_index(drop=True)
if (df_subset>0).any().all():
return df_subset
print('No such subset found that satisfies all constraints.')
return pd.DataFrame()
top_rows = 3
df = df[(df>0).any(axis=1)].sort_values(subset=['values'], ascending=False).reset_index(drop=True)
if len(df)>= top_rows:
desired_df = get_desired_subset(3)
else:
print('No such subset found that satisfies all constraints.')

最新更新