从 CSV 读取输入并将它们用于不同的功能

Posted

技术标签:

【中文标题】从 CSV 读取输入并将它们用于不同的功能【英文标题】:Reading inputs from CSV and using them for different functions 【发布时间】:2019-11-28 11:48:38 【问题描述】:

我有一个来自用户的带有输入的 csv 文件。第一列是 STATISTIC,它是我的 Python 代码中的函数,之后的列是每个统计信息的不同输入变量。

即WEIGHTED_MEAN 统计需要 VARIABLE_COLUMN 和 WEIGHT_VARIABLE。

我使用以下 python 代码读取了这个 csv 文件,其中 model_to_summarise 是我需要准备摘要的 df,reprot_inputs 是上面的 csv:

def parse_report_input_table(model_to_summarise, report_inputs):

    statistics_dict = 
        "WEIGHTED_MEAN": Reporting.weighted_mean,
        "MEAN": Reporting.get_mean_of_columns,
        "SUM": Reporting.get_sum_of_columns,
        "MAX": Reporting.get_max_of_columns,
        "MIN": Reporting.get_min_of_columns,
        "COUNT": Reporting.get_count_of_columns,
        "PERIOD_END_BALANCES": Reporting.period_end_balances,
        "PERIOD_START_BALANCES": Reporting.period_start_balances,
        "AVERAGE_BALANCES": Reporting.average_balances,
        "RATIO_V1": Reporting.ratio_calculation_v1,
        "RATIO_V2": Reporting.ratio_calculation_v2
    

    list_of_stat_reports = []
    group_by_variables = report_inputs["GROUP_BY_VARIABLES"][0].split(" || ")

    for index in report_inputs.index:
        function_to_call = statistics_dict[report_inputs.loc[index, "STATISTIC"]]
        if function_to_call == Reporting.weighted_mean:
            weighted_mean_report = function_to_call(model_to_summarise, group_by_variables,
                                                    report_inputs.loc[index, "VARIABLE_COLUMN"],
                                                    report_inputs.loc[index, "WEIGHT_VARIABLE"])
            list_of_stat_reports.append(weighted_mean_report)

        elif function_to_call in [
            Reporting.get_count_of_columns, Reporting.get_max_of_columns,
            Reporting.get_mean_of_columns, Reporting.get_min_of_columns,
            Reporting.get_sum_of_columns
                                    ]:
            columns_to_stat = report_inputs.loc[index, "COLUMNS_TO_STAT"].split(" || ")
            simple_stat_report = function_to_call(model_to_summarise,
                                                  group_by_variables,
                                                  columns_to_stat)
            list_of_stat_reports.append(simple_stat_report)

        elif function_to_call in [
            Reporting.period_end_balances,
            Reporting.period_start_balances,
            Reporting.average_balances
                                    ]:
            balances_df = function_to_call(model_to_summarise, group_by_variables,
                                                               report_inputs.loc[index, "UNMODIFIED_DATE_COLUMN"],
                                                               report_inputs.loc[index, "BALANCE_COLUMN"])
            list_of_stat_reports.append(balances_df)

        elif function_to_call == Reporting.ratio_calculation_v1:
            ratio_df_v1 = function_to_call(model_to_summarise, group_by_variables,
                                           report_inputs.loc[index, "NUMERATOR_VARIABLE"],
                                           report_inputs.loc[index, "DENOMINATOR_VARIABLE"],
                                           report_inputs.loc[index, "RATIO_NAME"])
            list_of_stat_reports.append(ratio_df_v1)

        elif function_to_call == Reporting.ratio_calculation_v2:
            ratio_df_v2 = function_to_call(model_to_summarise, group_by_variables,
                                           report_inputs.loc[index, "UNMODIFIED_DATE_COLUMN"],
                                           report_inputs.loc[index, "NUMERATOR_VARIABLE"],
                                           report_inputs.loc[index, "DENOMINATOR_VARIABLE"],
                                           report_inputs.loc[index, "RATIO_NAME"])
            list_of_stat_reports.append(ratio_df_v2)

        else:
            raise Exception("missing_stat is not available at the moment!"
                             .format(missing_stat=report_inputs.loc[index, "STATISTIC"]))

    return list_of_stat_reports, group_by_variables

此语句的第一个返回是创建的数据框列表(来自用户请求的 csv 文件中的统计信息)。

在这种情况下,列表将填充 weighted_mean_df、mean_df、period_end_balances_df 和 ratio_v2_df。

如您所见,每个函数都有不同的输入(有些类似,所以我在 if/else 语句中对它们进行了分组)。

字典-statistics_dict目前不是很大,为每个函数写if/elif就可以了。

但是这个 statistics_dict 将增加到 30-40,并且为每个统计量编写和 if/elif 并不是很好的编码。 有没有办法让它更通用/动态?

目前我为不同的统计数据编写了一个 if/elif,因为它们有不同的输入。

这是一个大问题,如果您需要更多解释,请告诉我!

【问题讨论】:

如何将整个 df 传递给每个函数,然后让函数提取它需要的数据? 我已经考虑过了,但我的团队和我自己都不喜欢它。因为这意味着每个函数的执行速度都会变慢。我们希望函数尽可能简单(只需进行计算)。 你的意思是这个函数的执行速度会变慢吗?将 df 传递给函数以提取相关数据并计算不会比提取相关数据并将其传递给函数慢 我知道这是一个解决方案,但我正在寻找是否有办法不修改统计函数。 IE。读取 csv 获取/提取输入并将它们传递给函数。 另外,我的计算函数是用 PySpark 编写的,在 pyspark 中我不能像在 pandas 中那样挑剔,比如 .loc 来选择行或索引等。我不想在一个函数中同时包含 pyspark 和 pandas。现在是 1-2 行。 【参考方案1】:

我用这样的课程做到了:

Class ExampleClass:
    def __init__(self, var1, var2, var3, all variables listed like that...):
        self.var1 = var1
        etc.


    def func1(self):
        func1 needs var1 and var3 so I use them by doing self.var1 and self.var3

    def func2(self):
        func2 needs var1 and var2 so I use them by self.var1 and self.var2

    etc. for all the functions

Afterwards I modify the parse_report_input_table function like this:

def parse_report_input_table(model_to_summarise, report_inputs):
    """
    Parse the csv table with inputs from the user.
    """
    list_of_individual_stat_reports = []
    group_by_variables = report_inputs["GROUP_BY_VARIABLES"][0].split(" || ")
    for index in report_inputs.index:
        reporting = Reporting(model_to_summarise,
                              group_by_variables,
                              report_inputs.loc[index, "NUMERATOR_VARIABLE"],
                              report_inputs.loc[index, "DENOMINATOR_VARIABLE"],
                              report_inputs.loc[index, "RATIO_NAME"],
                              report_inputs.loc[index, "VARIABLE_COLUMN"],
                              report_inputs.loc[index, "WEIGHT_VARIABLE"],
                              report_inputs.loc[index, "COLUMNS_TO_STAT"],
                              report_inputs.loc[index, "UNMODIFIED_DATE_COLUMN"],
                              report_inputs.loc[index, "BALANCE_COLUMN"])
        statistics_dict = 
                              "WEIGHTED_MEAN": reporting.weighted_mean,
                              "MEAN": reporting.get_mean_of_columns,
                              "SUM": reporting.get_sum_of_columns,
                              "MAX": reporting.get_max_of_columns,
                              "MIN": reporting.get_min_of_columns,
                              "COUNT": reporting.get_count_of_columns,
                              "PERIOD_END_BALANCES": reporting.period_end_balances,
                              "PERIOD_START_BALANCES": reporting.period_start_balances,
                              "AVERAGE_BALANCES": reporting.average_balances,
                              "RATIO_V1": reporting.ratio_calculation_v1,
                              "RATIO_V2": reporting.ratio_calculation_v2
        
        list_of_individual_stat_reports.append(statistics_dict[report_inputs.loc[index, "STATISTIC"]]())
    return list_of_individual_stat_reports, group_by_variables


这样,当我调用类时,会创建所有参数,但我实际调用的函数只需要它需要的参数。

将接受改进,因为我之前没有过多地使用 Python 类:)

【讨论】:

以上是关于从 CSV 读取输入并将它们用于不同的功能的主要内容,如果未能解决你的问题,请参考以下文章

如何从多个文本框输入中读取字符串并将它们存储在 Shiny 中的向量中?

从单个csv文件中读取两个完整的不同数据帧

Java非阻塞读取[关闭]

刮取网址的CSV列表并将结果输出到不同的CSV

从 bash 或 perl 脚本中读取 CSV [重复]

在 Azure ML Pipeline 的 train.py 中读取/装载 csv 文件