在 Pandas Dataframe 中获取具有非零列的前 11 行
Posted
技术标签:
【中文标题】在 Pandas Dataframe 中获取具有非零列的前 11 行【英文标题】:Get Top 11 rows with Non Zeros column in Pandas Dataframe 【发布时间】:2021-11-25 16:06:03 【问题描述】:我有一个如下所示的 pandas 数据框。它有 11 列仅包含 0 和 1,以及带有一些值的列,最后一列是标识符。我在处理数据框时遇到了问题。
我有一种情况,我需要根据“值”列选择前 11 行。 (松约束)
但棘手的部分是我必须以这样一种方式选择行,这样我就不会在这 11 行中得到任何零列。 (硬约束)。
所以我需要根据值选择前 11 行,并确保所有列都不为零。每列中至少有一个值应为 1。
我正在寻找一些通用解决方案,因为 Value 列中的值会发生变化,但我的目标是根据值选择 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
【问题讨论】:
所以你想找到 a = 1 的最高值,b = 1 的最高值,......? 【参考方案1】:使用自定义函数 - 先排序 values
,然后选择前 11 列
DataFrame.iloc
,通过DataFrame.astype
将浮点数转换为布尔值True
和False
s,因此如果至少有一个1
by DataFrame.rolling
和any
,则可以测试每个N 块,因此将行移动@987654334 @ 由NaN
s 填充,有必要用0
替换它们,转换为布尔值,如果所有行都有1
由DataFrame.all
进行可能的测试。
最后获取第一个True
的索引,但如果所有False
s在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
【讨论】:
它获得前 11 行的最大值,但列 a 和 b 都是零。我们需要找到最上面的行,但它应该包含的列不应该为零 我尝试更改为 all 然后它给了我带有列标题的空数据框。可能是因为它试图根据价值观进入前 11 名。 我想让它们中的所有第 11 列都非零。所有列中至少有一个元素应为 1。在您的上述解决方案中,col a 和 b 为零列 是的,通过您的解决方案,它以最终结果的方式选择行。 a 列和 b 列完全为零。我们需要以这样一种方式获取行,即每列中至少有 1 个元素为 1,否则根据最高值可以全部为零。因此,如果顶部值返回 1 列完全为零的行。我们可以将它与另一个交换,但非零列约束是必须的 @Waqarulislam - 答案已编辑。【参考方案2】:试试:
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.')
【讨论】:
它获得前 11 行的最大值,但列 a 和 b 都是零。我们需要找到最上面的行,但它应该包含的列不应该为零@tlentali 它获得具有最大值的前 11 行,但列 a 和 b 都是零。我们需要找到最上面的行,但它应该包含的列不应该为零 如果我理解正确,您的意思是得到 11 行,其中至少有一个非零元素,此外,在这 11 行的子集中,一列作为一个整体不应为零。这是你想要的吗? 是的,使用您的解决方案,它会以最终结果的方式选择行。 a 列和 b 列完全为零。我们需要以这样一种方式获取行,即每列中至少有 1 个元素为 1,否则根据最高值可以全部为零。因此,如果顶部值返回 1 列完全为零的行。我们可以将其与另一个交换,但非零列约束是必须的。 我认为(df>1)这个检查应该在列级别,它在数据框级别,所以只要每行不为零,就可以考虑零列。但我不确定 已编辑,立即查看。以上是关于在 Pandas Dataframe 中获取具有非零列的前 11 行的主要内容,如果未能解决你的问题,请参考以下文章
获取 Pandas DataFrame 列中字符串列表中的所有行 - 此模式具有匹配组
如何在 Pandas DataFrame 中一次获取多列的值计数?
为啥Pandas的DataFrame使用Series而非直接使用矩阵进行存储和数据操纵?
将具有相同列/索引的两个 pandas DataFrame 合并为一个 DataFrame