基于未知数量的列和值构造布尔掩码

2024-05-19 11:02:47 发布

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

我想基于数据帧中的一个或多个列以及这些列中的一个或多个值创建逻辑掩码。然后,应将这些掩码应用于另一列。在最简单的情况下,遮罩可能如下所示:

mask = data['a'] == 4
newData = data['c'][mask]

然而,也可能出现更复杂的情况:

mask = ((data['a'] == 4) | (data['a'] == 8)) & ((data['b'] == 1) | (data['b'] == 5))
newData = data['c'][mask]

此外,可能需要多个掩码。主要问题是我事先不知道

  • 需要多少面具,以及
  • 有多少列和
  • 这些列中有多少个值将定义掩码

因为这些信息将由用户提供。你知道吗

我想我可以让用户按照以下方式创建一个输入文件:

#  <maskName> - <columnName>: <columnValue(s)> - <columnName>: <columnValue(s)> - etc.
maskA - a: 4, 8 - b: 1, 5 - c: 1
maskB - a: 0, 8 - c: 2, 6, 10

targetColumn: d

然后我可以读取输入文件并在其上循环。通过适当地处理这些行,我可以确定所需掩码的数量、相关列、相关值以及应该应用掩码的列。我还可以将这些信息添加到列表和/或字典中。你知道吗

但是,我不知道如何最好地处理这个问题,因为我事先不知道掩码/列/值的数量,一旦知道它们,如何生成适当的掩码。任何帮助都将不胜感激。你知道吗


Tags: 文件数据用户信息data数量情况mask
1条回答
网友
1楼 · 发布于 2024-05-19 11:02:47

因为可以将字符串传递给df.query(),所以只要可以将输入格式转换为字符串,就很容易找到所需的子集。我为您的输入格式编写的解析器并不是非常优雅,但希望您能理解:

import pandas as pd
import numpy as np

maskA_str = "maskA - a: 4, 8 - b: 1, 5 - c: 1"
df = pd.DataFrame(
    {'a': np.random.randint(1, 10, 100),
     'b': np.random.randint(1, 10, 100),
     'c': np.random.randint(1, 10, 100)}
)

def create_query_str(mask_str):
    mask_name, column_conds = mask_str.split('-')[0], mask_str.split('-')[1:]
    query_str = '('
    column_strs =[]
    for cond in column_conds:
        cond_str = '('
        column, vals = cond.split(':')
        column = column.strip()
        test_strs = ['{c} == {v}'.format(c=column, v=val.strip())
                     for val in vals.split(',')]
        cond_str += ' | '.join(test_strs)
        cond_str += ')'
        column_strs.append(cond_str)
    query_str += ' & '.join(column_strs)
    query_str += ')'
    return query_str

create_query_str(maskA_str)
Out[17]: '((a == 4 | a == 8) & (b == 1 | b == 5) & (c == 1))'

# Can now be used directly in df.query()
df.query(create_query_str(maskA_str))

相关问题 更多 >

    热门问题