Фильтровать строки в пандах на основе порога - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть следующий фрейм данных.

    A1  A2  A3  B1  B2  B3  C1  C2  C3
0   0   0   1   1   1   1   0   1   1
1   0   0   0   0   0   0   0   0   0
2   1   1   1   0   1   1   1   1   1

Я хочу отфильтровать его по группам столбцов и появлению ненулевых значений. Я написал следующее, чтобы добиться этого.

import pandas as pd
df = pd.read_csv("TEST_TABLE.txt", sep='\t')
print(df)
group1 = ['A1','A2','A3']
group2 = ['B1','B2','B3']
group3 = ['C1','C2','C3']
df2 = df[(df[group1] !=0).any(axis=1) & (df[group2] !=0).any(axis=1) & (df[group3] !=0).any(axis=1)]
print(df2)

Вывод был идеальным:

    A1  A2  A3  B1  B2  B3  C1  C2  C3
0   0   0   1   1   1   1   0   1   1
2   1   1   1   0   1   1   1   1   1

Теперь, как изменить код так, чтобы я мог наложить пороговое значение для «любого». то есть сохраните строки для каждой группы, по крайней мере, с 2 ненулевыми значениями. Следовательно, окончательный вывод даст

   A1  A2  A3  B1  B2  B3  C1  C2  C3
2   1   1   1   0   1   1   1   1   1

Заранее спасибо.

1 Ответ

0 голосов
/ 06 сентября 2018

Вы можете создавать логические маски в цикле с помощью sum для значений, отличных от 0, со сравнением на ge (>=) и последними уменьшением масок :

groups = [group1,group2,group3]
df2 = df[np.logical_and.reduce([(df[g]!=0).sum(axis=1).ge(2) for g in groups])]

print(df2)
   A1  A2  A3  B1  B2  B3  C1  C2  C3
2   1   1   1   0   1   1   1   1   1

Detail

print([(df[g]!=0).sum(axis=1).ge(2) for g in groups])

[0    False
1    False
2     True
dtype: bool, 0     True
1    False
2     True
dtype: bool, 0     True
1    False
2     True
dtype: bool]
...