我有一个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
将浮点数转换为布尔值True
和False
s,因此如果DataFrame.rolling
至少有一个1
被any
填充,则可能测试每N块,因此N
移位的行被NaN
s填充,有必要将它们替换为0
,转换为布尔值,如果所有行都有1
被DataFrame.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.')