【问题标题】:Compare columns while iterating over rows in Python and increment value在 Python 中迭代行时比较列并增加值
【发布时间】:2020-02-26 20:26:29
【问题描述】:

我有一个带有成对列的数据帧(例如,CS 与 CS_Capacity 一起使用,RD 与 RD_Capacity 一起使用,等等)。我有一列包含月份,然后每组对都有一个值。

我想在 1 月份比较 CS 和 CS_Capacity,如果 CS_Capacity 大于 CS,我想增加 CS 使 CS = CS_Capacity,然后将 CSval 减少相同的量。然后我想去下个月做同样的事情,直到 CSval = 0。

样本数据:

data = [['2020-01-31', 3, 6, 7, 11], ['2020-02-29', 13 ,11, 8, 13], ['2020-03-31', 22, 19, 8 ,5], ['2020-04-30', 2, 3, 6, 4], ['2020-05-31', 19, 6, 4, 5], 
        ['2020-06-30', 2, 14, 6, 8], ['2020-07-31', 5, 4, 3, 6], ['2020-08-31', 5, 11, 7, 19], ['2020-09-30',2,1, 4, 5], ['2020-10-31',29, 16, 14, 10], 
        ['2020-11-30',2, 4, 6, 7], ['2020-12-31', 25, 20, 5, 3]] 

# Create the pandas DataFrame 
df = pd.DataFrame(data, columns = ['StartDate', 'RD', 'RD_Capacity', 'CS', 'CS_Capacity'], dtype=('<M8[ns]'))
df['CS_Capacity'] = df['CS_Capacity'].astype('int')
df['CS'] = df['CS'].astype('int')
df['RD_Capacity'] = df['RD_Capacity'].astype('int')
df['RD'] = df['RD'].astype('int')

CSval = 40
RDval = 22

pairs = [('CS', 'CS_Capacity', CSval), ('RD', 'RD_Capacity', RDval)]

我正在循环遍历此处的选项以进行递增和递减:


for val1, val2, val3 in pairs:
    df['New Target' + val1] = df[val1] #create new column to store new target- set equal to val1
    df['Value' + val1 + 'Original'] = val3 # starting value incremented row by row
    for index, row in df.iterrows(): # loop through rows
        if (df[val1][index] < df[val2][index]): # for first row, if val1 is less than val2
            delta = df[val2] - df[val1] # create a delta so you know how much to decrement val3
            df['New Target' + val1]= df[val2] # set new target equal to val2
            val3 = val3 - delta # decrement val3
            df['Delta' + val1] = delta
            df['Value' + val1] = val3 # decremented value
        if (df[val1][index] > df[val2][index]): # for first row, if val2 is less than val1
            delta = df[val1] - df[val2] # create a delta so you know how much to increment val3
            df['New Target' + val1]= df[val2] # set new target equal to val2
            val3 = val3 + delta # increment val3                        
            df['Delta' + val1] = delta
            df['Value' + val1] = val3 # incremented value

虽然此代码有效,但我遇到了一些问题:

  1. df['Value' + val1] 没有适当地增加或减少。
  2. 我想将新的 val3 结转到下一行,这样我就可以跟踪每行是如何累积递增或递减的。

因此,如果开始时 CSval = 40,并且 delta 在 1 月份为 3(-),则 df['Value' + val1] 应该等于 37。 然后,下一行中的 df['Value' + val1 + 'Original'] 应该从 37 开始。由于下一行的 delta 为 2(+),因此 df['Value' + val1] 应该等于 39。

当前输出:

所需输出:

我哪里错了?我希望 val3 在 if 语句中增加,这样应该可以工作。我错过了什么?

谢谢大家!

【问题讨论】:

  • 您能否显示您期望的输出,因为您的代码非常密集并且不完全清楚您在问什么
  • 增加了输出预期!

标签: python pandas comparison increment itertools


【解决方案1】:

这似乎比你做的要简单得多。此解决方案是否符合您的要求?

df['CSval'] = -(df['CS_Capacity'] - df['CS']).cumsum() + CSval
mask = (df['CSval']>=0) & (df['CS_Capacity'] > df['CS'])
df.loc[mask, 'CS'] = df.loc[mask, 'CS_Capacity']

在迭代结束时,CSVal 的值为 22,数据框如下所示:

0  2020-01-31   3            6  11           11   36.0
1  2020-02-29  13           11  13           13   31.0
2  2020-03-31  22           19   8            5   34.0
3  2020-04-30   2            3   6            4   36.0
4  2020-05-31  19            6   5            5   35.0
5  2020-06-30   2           14   8            8   33.0
6  2020-07-31   5            4   6            6   30.0
7  2020-08-31   5           11  19           19   18.0
8  2020-09-30   2            1   5            5   17.0
9  2020-10-31  29           16  14           10   21.0
10 2020-11-30   2            4   7            7   20.0
11 2020-12-31  25           20   5            3   22.0

即使该值低于 0,此解决方案也会创建一个 CSVal,但它仅在 CSval 高于零时更改 CS 值。如果您愿意,您可以在之后清理数据框,只需执行以下操作

【讨论】:

  • 是的,但我需要知道每个月的 CSval,这样我才能跟踪它何时达到零。我实际上并不需要增量 - 只是显示所以我可以进行质量检查。这是一个很好的简单解决方案 - 谢谢!您将如何重新添加 CSval 列?
  • 那么 CSval 永远不会达到 0,但请参阅更新。我还看到您也想增加 CSVal
  • 是的,但这只是虚拟数据。在我的真实数据中,确实如此。谢谢!
  • 现在试试
  • 编辑了解决方案,因为我也过于复杂了。这可以在三行小代码中完成
猜你喜欢
  • 2023-01-13
  • 2020-07-12
  • 2018-10-27
  • 1970-01-01
  • 2020-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多