假设我们在熊猫中有不同的数据帧结构

# creating the first dataframe
df1 = pd.DataFrame({
  "width": [1, 5],
  "height": [5, 8]})

# creating second dataframe
df2 = pd.DataFrame({
  "a": [7, 8],
  "b": [11, 23],
  "c": [1, 3]})

# creating second dataframe
df3 = pd.DataFrame({
  "radius": [7, 8],
  "height": [11, 23]})


通常,可能有两个以上的数据帧。现在,我想创建一个将列名称映射到特定函数的逻辑,以创建新的列“度量”(将其视为两列的面积和三列的体积)。我想指定列名称集成

column_name_ensembles = {
    "1": {
       "ensemble": ['height', 'width'],
       "method": area},
    "2": {
       "ensemble": ['a', 'b', 'c'],
       "method": volume_cube},
    "3": {
       "ensemble": ['radius', 'height'],
       "method": volume_cylinder}}

def area(width, height):
    return width * height

def volume_cube(a, b, c):
    return a * b * c

def volume_cylinder(radius, height):
    return (3.14159 * radius ** 2) * height


现在,area函数将为数据框df1['metric'] = df1['height'] * df2['widht']创建一个新列,而volumen函数将为数据框df2['metic'] = df2['a'] * df2['b'] * df2['c']创建一个新列。请注意,函数可以具有任意形式,但是它将集合作为参数。所需的功能metric(df, column_name_ensembles)应采用任意数据帧作为输入,并通过检查列名来决定应应用哪个功能。

输入输出行为示例

df1_with_metric = metric(df1, column_name_ensembles)
print(df1_with_metric)
# output
#    width height metric
#  0 1     5      5
#  1 5     8      40
df2_with_metric = metric(df2, column_name_ensembles)
print(df2_with_metric)
# output
#    a  b  c  metric
#  0 7  11 1  77
#  1 8  23 3  552
df3_with_metric = metric(df3, column_name_ensembles)
print(df3_with_metric)
# output
#    radius  height  metric
#  0 7       11      1693.31701
#  1 8       23      4624.42048


理想的解决方案是将数据框和column_name_ensembles作为参数并返回添加了适当“度量”的数据框的函数。

我知道可以通过多个if和else语句来实现,但这似乎并不是最明智的解决方案。也许有一种设计模式可以解决这个问题,但是我不是设计模式的专家。

感谢您阅读我的问题!我期待着您的好答案。

最佳答案

您可以使用inspect模块自动提取参数名称,然后将参数名称的frozenset直接映射到度量标准函数:

import inspect

metrics = {
    frozenset(inspect.signature(f).parameters): f
    for f in (area, volume_cube, volume_cylinder)
}


然后对于给定的数据帧,如果保证所有列都是相关度量的参数,则可以简单地查询该字典:

def apply_metric(df, metrics):
    metric = metrics[frozenset(df.columns)]
    args = tuple(df[p] for p in inspect.signature(metric).parameters)
    df['metric'] = metric(*args)
    return df


如果输入数据框的列数超过度量标准功能所需的列,则可以使用集合交集查找相关度量标准:

def apply_metric(df, metrics):
    for parameters, metric in metrics.items():
        if parameters & set(df.columns) == parameters:
            args = tuple(df[p] for p in inspect.signature(metric).parameters)
            df['metric'] = metric(*args)
            break
    else:
        raise ValueError(f'No metric found for columns {df.columns}')
    return df

关于python - Pandas 灵活确定指标,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60576785/

10-11 22:54
查看更多