Python - фильтрует набор данных на основе значений столбцов другого набора данных - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть два набора данных:

Первый набор данных выглядит следующим образом:

| Key 1 | Value 1 | Key 2 | Value 2 | Key 3 | Value 3|

| abc   |  True   | bcd   | False   | cde   | False  |
| bcd   |  False  | cde   | True    | def   | False  |
| def   |  False  | abc   | True    | None  | N/A    |

Вторые данные выглядят так:

| abc    | bcd     | cde   | def     | status    |

| False  |  False  | True  | False   |  Success  |
| True   |  False  | False | False   |  Failure  |
| False  |  True   | True  | True    |  Success  |
| False  |  False  | True  | False   |  Failure  |
| True   |  False  | False | False   |  Success  |
| False  |  True   | True  | True    |  Success  |
| False  |  False  | True  | True    |  Success  |
| True   |  False  | False | False   |  Failure  |
| True   |  True   | True  | False   |  Failure  |

Теперь для каждой строки в первомнабор данных, я хочу забрать пары ключ-значение и применить их в качестве фильтров во втором наборе данных, т.е. подмножество строк из второго подмножества.Затем подсчитайте количество применимых строк, число успешных попыток, число неудачных попыток.

Таким образом, первый набор данных преобразуется в:

| Key 1| Value 1| Key 2| Value 2| Key 3| Value 3| Row Count | Successes| Failures|

| abc  |  True  | bcd  | False  | cde  | False  | 3         |1         |2   |
| bcd  |  False | cde  | True   | def  | False  | 2         |1         |1   |
| def  |  False | abc  | True   | None | N/A    | 4         |1         |3   |

Объяснение:

В первом ряду (первого набора данных): abc - True;bcd - Ложь;cde - Ложь.Применив эти фильтры ко второму набору данных, у нас останутся следующие строки:

| abc    | bcd     | cde   | def     | status    |

| True   |  False  | False | False   |  Failure  |
| True   |  False  | False | False   |  Success  |
| True   |  False  | False | False   |  Failure  |

Количество строк: 3 Сбой: 2 Успех: 1

1 Ответ

0 голосов
/ 14 февраля 2019

Я считаю, что вам нужно:

from collections import Counter

#create dictionaries of boolean values for each row
L = [{a:b for a, b in (zip(v[::2], v[1::2])) if isinstance(b, bool)} 
          for k, v in df1.T.to_dict('l').items()]
print (L)
[{'abc': True, 'bcd': False, 'cde': False}, 
 {'bcd': False, 'cde': True, 'def': False}, 
 {'def': False, 'abc': True}]

#match with df2 and count index values by Counter
df22 = df2.set_index('status')
out = [Counter(df22.index[np.logical_and.reduce([df22[k] == v 
       for k, v in x.items()])]) for x in L]
print (out)
[Counter({'Failure': 2, 'Success': 1}), 
 Counter({'Success': 1, 'Failure': 1}),
 Counter({'Failure': 3, 'Success': 1})]

#create DataFrame
df2 = pd.DataFrame(out, index=df1.index).fillna(0).astype(int)
#insert total row for first position
df2.insert(0, 'Row Count', df2.sum(axis=1))
#join together
df = df1.join(df2)
print (df)
  Key 1  Value 1 Key 2  Value 2 Key 3 Value 3  Row Count  Failure  Success
0   abc     True   bcd    False   cde   False          3        2        1
1   bcd    False   cde     True   def   False          2        1        1
2   def    False   abc     True  None     NaN          4        3        1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...