【问题标题】:Python - Filter a dataset based on column values of another datasetPython - 根据另一个数据集的列值过滤数据集
【发布时间】:2019-07-08 04:12:42
【问题描述】:

我有两个数据集:

第一个数据集如下所示:

| 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

【问题讨论】:

  • 你尝试了什么?显示您的代码。
  • 您能否将一些示例数据更改为两个数据框并添加预期输出 - 所有行?因为需要minimal, complete, and verifiable example。是否可以将abc 列更改为False, True, FalsecdeTrue, False, True,也可以将Value 3 更改为False, True, NaN 以获得更通用的解决方案?
  • @jezrael 添加了这些值。感谢您的评论
  • 你能检查我的答案吗?我得到了一些不同的输出。也可以解释更多Row Count专栏?
  • 如果我不明白,是否可以向两个数据框添加更多行?例如 3-4 个新的?

标签: python-3.x pandas numpy dictionary


【解决方案1】:

我相信你需要:

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

【讨论】:

  • 直到我看到答案,我才明白这个问题,:)
  • @anky_91 - 是的,有点忙,但晚饭后检查一下。
  • @jezrael 你的答案只是照顾“真”过滤器,它还需要照顾“假”过滤器,因为我们正在寻找 df1 在 df2 中出现的精确匹配
猜你喜欢
  • 2019-06-12
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 2018-11-12
  • 2018-12-11
相关资源
最近更新 更多