Pandas:从数据帧返回行,其中多个列子集不是z

2024-04-19 15:35:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个名为df的数据帧

数据框中的列可以按逻辑分组。因此,我将列名分组在列表A、B、C中,其中:

A = [column_1, column_2, column_3]
B = [column_4, column_5, column_6]
C = [column_7, column_8, column_9]

除了列列\u 1到列\u 9之外,df还有一个称为“文件名\u ID”的列,用作索引,因此不分组。列1到列9只包含0和1的值。你知道吗

现在我想过滤数据帧,使它只包含每个组(A,B,C)至少有一个非零值的行。因此,我只想保留具有相应文件名的行,以满足此条件。你知道吗

我已经为每个组创建了一个单独的数据帧:

df_A = df.loc[(df[A]!=0).any(axis=1)]
df_B = df.loc[(df[B]!=0).any(axis=1)]
df_C = df.loc[(df[C]!=0).any(axis=1)]

但是,我不知道如何同时应用所有的条件,也就是说,如何创建一个新的数据帧,其中所有的行都填满了每个逻辑列组中至少有一个非零值的条件。你知道吗


Tags: 数据iddf列表文件名anycolumn逻辑
3条回答

创建了一个包含示例数据的csv文件

样本输入:

ID  a1  a2  a3  a4  a5  a6  a7  a8  a9
1   1   1   1   1   1   1   1   1   1
2   0   0   0   1   0   0   0   1   0
3   0   1   0   0   0   0   1   0   0
4   0   0   0   0   1   0   1   0   1
5   1   1   0   1   1   1   1   0   1
6   0   0   0   0   1   0   0   1   0
7   1   0   1   1   1   0   1   1   1
8   1   1   1   0   1   1   1   0   1
9   0   0   0   1   0   1   0   0   0
10  0   0   1   0   0   0   0   0   0
11  1   0   1   0   1   1   0   1   1
12  1   1   0   1   0   1   1   0   1

import pandas as pd
df = pd.read_csv('check.csv')
df['sumA'] = df.a1+df.a2+df.a3
df['sumB'] = df.a4+df.a5+df.a6
df['sumC'] = df.a7+df.a8+df.a9
new_df = df[(df.sumA>1)&(df.sumB>1)&(df.sumC>1)]
new_df = new_df.drop(['sumA','sumB','sumC'],axis=1)

输出:

    ID  a1  a2  a3  a4  a5  a6  a7  a8  a9
0   1   1   1   1   1   1   1   1   1   1
4   5   1   1   0   1   1   1   1   0   1
6   7   1   0   1   1   1   0   1   1   1
7   8   1   1   1   0   1   1   1   0   1
10  11  1   0   1   0   1   1   0   1   1
11  12  1   1   0   1   0   1   1   0   1

设置

np.random.seed([3, 1415])

df = pd.DataFrame(
    np.random.randint(2, size=(10, 9)),
    columns=[f"col{i + 1}" for i in range(9)]
)

df

   col1  col2  col3  col4  col5  col6  col7  col8  col9
0     0     1     0     1     0     0     1     0     1
1     1     1     1     0     1     1     0     1     0
2     0     0     0     0     0     0     0     0     0
3     1     0     1     1     1     1     0     0     0
4     0     0     1     1     1     1     1     0     1
5     1     1     0     1     1     1     1     1     1
6     1     0     1     0     0     0     1     1     0
7     0     0     0     0     0     1     0     1     0
8     1     0     1     0     1     0     0     1     1
9     1     0     1     0     0     1     0     1     0

解决方案

创建词典

m = {
    **dict.fromkeys(['col1', 'col2', 'col3'], 'A'),
    **dict.fromkeys(['col4', 'col5', 'col6'], 'B'),
    **dict.fromkeys(['col7', 'col8', 'col9'], 'C'),
}

然后groupby基于axis=1

df[df.groupby(m, axis=1).any().all(1)]

   col1  col2  col3  col4  col5  col6  col7  col8  col9
0     0     1     0     1     0     0     1     0     1
1     1     1     1     0     1     1     0     1     0
4     0     0     1     1     1     1     1     0     1
5     1     1     0     1     1     1     1     1     1
8     1     0     1     0     1     0     0     1     1
9     1     0     1     0     0     1     0     1     0

注意那些没有成功的

   col1  col2  col3  col4  col5  col6  col7  col8  col9
2     0     0     0     0     0     0     0     0     0
3     1     0     1     1     1     1     0     0     0
6     1     0     1     0     0     0     1     1     0
7     0     0     0     0     0     1     0     1     0

您也可以有这样的列:

cols = [['col1', 'col2', 'col3'], ['col4', 'col5', 'col6'], ['col7', 'col8', 'col9']]
m = {k: v for v, c in enumerate(cols) for k in c}

执行相同的groupby

请尝试以下操作:

column_groups = [A, B, C]
masks = [(df[cols] != 0).any(axis=1) for cols in column_groups]
full_mask = np.logical_and.reduce(masks)
full_df = df[full_mask]

相关问题 更多 >