比较python中单列pandas数据框的值(将perl转换为python代码)

我正在尝试将 perl 代码转换为 python,以便将列简单地乘以一些常量。我创建了一个带有多列浮点值的 pandas 数据框。这是 components.csv 文件的示例。


      NA  MULT   NOA   NOB  CHARGE   EX

0    8.0   1.0  24.0  24.0     0.0  1.0

1    8.0   1.0  24.0  24.0     0.0  1.0

2    8.0   1.0   6.0   6.0     0.0  1.0

3   20.0   1.0  18.0  18.0     0.0  1.0

4   23.0   1.0  21.0  21.0     0.0  1.0

5   26.0   1.0  24.0  24.0     0.0  1.0

6   11.0   1.0  13.0  13.0     0.0  0.0

7   16.0   1.0  19.0  19.0     1.0  0.0

8    1.0   1.0   4.0   4.0    -1.0  0.0

9   17.0   1.0  23.0  23.0     0.0  0.0

10   1.0   1.0   4.0   4.0     0.0  0.0

11   1.0   1.0   4.0   4.0     0.0  0.0

初始参数为:


$A1 = 9.3692400791;

$A2 = 9.4492960287;

$B  = 3.8320915550;

$C  = 9.5936653352;

$D  = 1.8739215238;

$E  = 2.4908584058;

预期的输出是单列(d5):


Df5

-0.2249

-0.2249

-0.0562

-0.1686

-0.1968

-0.2249

-0.1218

-0.1780

-0.0384

-0.2155

-0.0375

-0.0375

使用以下方法解析数据帧后:


pd.set_option('precision', 8)

df = pd.read_csv("unscaled_components_delimit.csv", delimiter= ",", header=0)

我有多个条件要检查,例如以下脚本:


if (df['NA'] > 1).any():

    print(True)

elif (df['NA'] == 1).any():

    print(False)

然而,上面的代码只打印一个 True 值,即使在标题为 NA 的列中有多个 1.0 值,这意味着它不会传递给第二个 elif。我使用了函数 any() ,也许应该使用我目前不知道的另一个函数。因此,有人可能会为此提出解决方案吗?


目标是将列(标题 NA)的每个元素与数字 1(大于或等于)进行比较。然后,对其他列执行一些具有其他条件的操作。


我将不胜感激任何帮助或建议。


为了更清楚起见,以下代码包含具有所有必需条件的最终所需代码:


if (df['NA'] > 1).any():

    if (df['MULT'] == 1).any():

        if ((df['NOB'] != 1).any() or (df['NOB'] ==1).any()):

            d5 = -A1*df['NOB']

        elif((df['NOB'] == 1).any()):

            d5 = -E*df['NOB']

    else:

        d5 = -A2*df['NOB'] - B*(df['NOA']-df['NOB'])

三国纷争
浏览 226回答 2
2回答

慕容708150

已经解释了为什么您对 NA 列的比较没有返回您期望的结果。但是,我会以与他不同的方式进行比较。这是一个小片段,应该可以帮助您理解:# a series of bools, indicating for which index our condition is truena_gt_1_series = df["NA"] > 1print(na_gt_1)# creating a new column based on the values of the NA columndf["na_gt_1"] = na_gt_1_seriesprint(df)现在,由于这里的条件相当复杂,我认为使用 pandas 的 apply 函数会更简单,它沿着 DataFrame 的某个轴应用一个函数。def get_row_df5(row):    df5 = 0    if row["NA"] > 1:        if row["MULT"] == 1:            if row["NOB"] == 1:                df5 = -A1 * row["NOB"]        else:            df5 = -A2 * row["NOB"] - B * (row["NOA"] - row["NOB"])    elif row["NA"] == 1:        if row["MULT"] == 1:            if row["EX"] == 0 and row["NOB"] == 4 and row["CHARGE"] == 0:                df5 = -A1 * row["NOB"]            elif row["NOB"] != 1 or row["NOB"] == 1 and row["EX"] != 0:                df5 = -C * row["NOB"]            elif row["NOB"] == 1 and row["EX"] == 0:                df5 = -E * row["NOB"]        else:            df5 = -C * row["NOB"] - D * (row["NOA"] - row["NOB"])    return df5df5_res = df.apply(func=get_row_df5, axis=1)不幸的是,这种简单性是有代价的。对于通过复制示例数据制作的 120,000 行 DataFrame,应用解决方案需要约 4 秒,而以下解决方案需要约 40 毫秒(快 100 倍)。def get_df5_broad(df_in):    na_lt_1 = df_in["NA"] > 1    na_eq_1 = df_in["NA"] == 1    mult_eq_1 = df_in["MULT"] == 1    mult_ne_1 = ~mult_eq_1    res_series = pd.Series(np.zeros(shape=df_in.shape[0]))    res_series.loc[na_lt_1 & mult_eq_1 & (df_in["NOB"] == 1)] = -A1 * df_in["NOB"]    res_series.loc[na_lt_1 & mult_ne_1] = -A2 * df_in["NOB"] - B * (df_in["NOA"] - df_in["NOB"])    res_series.loc[na_eq_1 & mult_eq_1 & (df_in["EX"] == 0) & (df_in["NOB"] == 4) & (df_in["CHARGE"] == 0)] = -A1 * df_in["NOB"]    res_series.loc[na_eq_1 & mult_eq_1 & ((df_in["NOB"] != 1) | ((df_in["NOB"] == 1) & (df_in["EX"] != 0)))] = -C * df_in["NOB"]    res_series.loc[na_eq_1 & mult_eq_1 & (df_in["NOB"] == 1) & (df_in["EX"] == 0)] = -E * df_in["NOB"]    res_series.loc[na_eq_1 & mult_ne_1] = -C * df_in["NOB"] - D * (df_in["NOA"] - df_in["NOB"])    return res_series最后,下一个方法是两全其美的方法。它的设计和简单性与使用 apply 的方法相似,但仅比之前的高性能版本慢 5 倍。def get_df5_tupe(tupe):    df5 = 0    if tupe.NA > 1:        if tupe.MULT == 1:            if tupe.NOB == 1:                df5 = -A1 * tupe.NOB        else:            df5 = -A2 * tupe.NOB - B * (tupe.NOA - tupe.NOB)    elif tupe.NA == 1:        if tupe.MULT == 1:            if tupe.EX == 0 and tupe.NOB == 4 and tupe.CHARGE == 0:                df5 = -A1 * tupe.NOB            elif tupe.NOB != 1 or tupe.NOB == 1 and tupe.EX != 0:                df5 = -C * tupe.NOB            elif tupe.NOB == 1 and tupe.EX == 0:                df5 = -E * tupe.NOB        else:            df5 = -C * tupe.NOB - D * (tupe.NOA - tupe.NOB)    return df5def get_df5_iter(df_in):    return pd.Series((get_df5_tupe(curr) for curr in df_in.itertuples(index=False)))注意:由于 OP 中的逻辑歧义,这些方法并不总是返回正确的答案。一旦正确的布尔表达式可用,我将立即编辑我的解决方案。

忽然笑

这个块在这里:if (df['NA'] > 1).any():    print(True)elif (df['NA'] == 1).any():    print(False)将始终打印 True 因为列 'NA' 的值大于 1,因此不会评估第二个 elif。根据您的评论,如果我没记错的话,我认为您想遍历 DataFrame 并评估每个元素。你可以尝试这样的事情:for val in df['NA']:    if val > 1:        print(True)    elif val == 1:        print(False)这将评估列“NA”的每个元素,对于您的实际用例,您将想知道给定 val 的索引,这可以使用enumerate. 例如:for (idx, val) in enumerate(df['NA']):    if val > 1:        d5 = -A1 * df['NOB'].iloc[idx]    elif val == 1:        d5 = E * df['NOB'].iloc[idx]idx是当前元素的索引,您可以使用 访问该索引处其他列的元素iloc。我希望这会有所帮助,祝你好运。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python