在Pandas中,找到另一列中存在NaN值的行的某一列的值之和。

huangapple go评论94阅读模式
英文:

Find the sum of values in rows of one column for where the other column has NAN in Pandas

问题

我有一个包含列A和B的数据框。列A中的数据是不连续的,其中一些行是NAN,而B中的数据是连续的。我想创建第三列,对于每组A中的NAN行,它将具有这些相同行中B的值的总和加上B中的下一个有效值。

对于A中的NAN和在有效数字后的行,C中的所有其他值应为NAN。

示例:

  1. data = {
  2. 'A': [1, 1, None, None, 2, 5, None, None, 3, 4, 3, None, 5],
  3. 'B': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130]
  4. }

除了需要B的总和加上B中的下一个有效值的行之外,其他行都可以正常工作。

我使用以下代码。但是目前看起来有点混乱。

  1. result = df.groupby(df['A'].isnull().cumsum())['B'].sum().reset_index()
  2. df_result = pd.DataFrame({'C': result['Pumped']})
  3. df_result.loc[1:, 'C'] -= result.loc[0, 'Pumped']
  4. df.loc[~mask, 'C'] = df.loc[~mask, 'Pumped']
  5. valid_rows_after_nan = df['dWL'].notnull() & mask.shift(1).fillna(False)
  6. df.loc[valid_rows_after_nan, 'C'] = df_result
  7. print(df)

我希望输出的结果如下所示:

  1. data = {
  2. 'A': [1, 1, None, None, 2, 5, None, None, 3, 4, 3, None, 5],
  3. 'B': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130],
  4. 'C': [10, 20, None, None, 120, 60, None, None, 240, 100, 110, None, 5]
  5. }
英文:

I have a dataframe with columns A and B. Column A has non continuous data where some of the rows are NAN and B has continuous data. I would like to create a third column where for each set of A rows with NAN it will have the sum of values in those same rows in B + the next valid value in B.
All other values in C should be NAN for NAN in A AND the value of B for rows following a valid number in A.
Example:

  1. data = {
  2. 'A': [1, 1, None, None, 2, 5, None, None,3 ,4, 3, None , 5],
  3. 'B': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130]}

Everything works fine except for the rows where I need the sum of B + next valid value in B.
I use the following code. I have this code but is seems it's a mess by now.

  1. `result = df.groupby(df['A'].isnull().cumsum())['B'].sum().reset_index()
  2. df_result = pd.DataFrame({'C': result['Pumped']})
  3. df_result.loc[1:, 'C'] -= result.loc[0, 'Pumped']
  4. df.loc[~mask, 'C'] = df.loc[~mask, 'Pumped']
  5. valid_rows_after_nan = df['dWL'].notnull() & mask.shift(1).fillna(False)
  6. df.loc[valid_rows_after_nan, 'C'] = df_result
  7. print(df)`

I would like the output to look like this:

  1. `data = {
  2. 'A': [1, 1, None, None, 2, 5, None, None,3 ,4, 3, None , 5],
  3. 'B': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130],
  4. 'C': [10, 20, None, None, 120, 60, None, None, 240, 100, 110, None, 5]
  5. }

答案1

得分: 4

使用groupby.transform的简单版本:

  1. # 识别非NA值并反转
  2. m = df.loc[::-1, 'A'].notna()
  3. # 对前面的NA进行分组求和,并在NA处进行掩码
  4. df['C'] = df.groupby(m.cumsum())['B'].transform('sum').where(m)

输出结果:

  1. A B C
  2. 0 1.0 10 10.0
  3. 1 1.0 20 20.0
  4. 2 NaN 30 NaN
  5. 3 NaN 40 NaN
  6. 4 2.0 50 120.0
  7. 5 5.0 60 60.0
  8. 6 NaN 70 NaN
  9. 7 NaN 80 NaN
  10. 8 3.0 90 240.0
  11. 9 4.0 100 100.0
  12. 10 3.0 110 110.0
  13. 11 NaN 120 NaN
  14. 12 5.0 130 250.0
英文:

A simple version using groupby.transform:

  1. # identify the non-NA and reverse
  2. m = df.loc[::-1, 'A'].notna()
  3. # group the preceding NA, sum, mask where NA
  4. df['C'] = df.groupby(m.cumsum())['B'].transform('sum').where(m)

Output:

  1. A B C
  2. 0 1.0 10 10.0
  3. 1 1.0 20 20.0
  4. 2 NaN 30 NaN
  5. 3 NaN 40 NaN
  6. 4 2.0 50 120.0
  7. 5 5.0 60 60.0
  8. 6 NaN 70 NaN
  9. 7 NaN 80 NaN
  10. 8 3.0 90 240.0
  11. 9 4.0 100 100.0
  12. 10 3.0 110 110.0
  13. 11 NaN 120 NaN
  14. 12 5.0 130 250.0

huangapple
  • 本文由 发表于 2023年7月27日 15:38:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76777484.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定