【问题标题】:Calculating Difference Once Column turns from False to True一旦列从假变为真,计算差异
【发布时间】:2021-10-04 13:29:30
【问题描述】:

我有一个 Pandas 数据框,其组织方式如下:

+-------+-------------------+---------+
| Name  |       Ready       | Apples  |
+-------+-------------------+---------+
| Alice | false             |    1    |
| Bob   | false             |    3    |
| Chris | true              |    10   |
| Alice | true              |    5    |
| Bob   | true              |    7    |
| Dave  | false             |    NaN  |
+-------+-------------------+---------+

我想计算它们在准备好计数后所拥有的苹果的差异 - 所以这将是当错误变为正确的时候。如果他们已经准备好了,我只想要他们拥有的苹果数量。如果他们从来没有准备好,那么就只是 NaN。问题是,在它变为 True 之前,每个人可能有多个 False 行。例如,我们可能会看到 Alice 在她最终准备好之前 3 次没有准备好。

有没有办法对名称进行分组,然后找出 false --> true 来计算苹果的差异?我希望我的输出表看起来像:

+-------+--------------------+
| Name  |    Collected Apples|
+-------+--------------------+
| Alice | 4 (cuz 5-1 = 4)    |
| Bob   | 4                  |
| Chris | 10                 |
| Dave  | NaN                |
+-------+--------------------+

有什么想法吗?谢谢!

【问题讨论】:

  • 按名称分组,然后在每个子df中,向前移动,找到发生变化的行,提取差异。

标签: pandas dataframe group-by difference


【解决方案1】:

假设每个名称最多有一个True 行和一个False 行。我们可以pivot 然后从False 中减去True

# Pivot to Wide Form
result_df = df.pivot(index='Name', columns='Ready', values='Apples')
# Calculate Results
result_df = (
        result_df[True] - result_df[False].fillna(0)  # Subtract True from False
).reset_index(name='Collected Apples')

result_df:

    Name  Collected Apples
0  Alice               4.0
1    Bob               4.0
2  Chris              10.0
3   Dave               NaN

DataFrame 和导入:

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Chris', 'Alice', 'Bob', 'Dave'],
    'Ready': [False, False, True, True, True, False],
    'Apples': [1.0, 3.0, 10.0, 5.0, 7.0, np.nan]
})

【讨论】:

  • 如果可以有多个 True 行,这是否有效?
  • 没有。这就是我在第一行中提出的警告:“假设每个名称最多有一个 True 行”。 Corralien 通过求和求和来实现。
  • 等等。拥有多个 True 行是什么意思?您想计算每个人从 True 到 True 的值吗?就像爱丽丝有多个假然后是真,然后是多个假和真。你会想要 2 笔钱吗?
  • 这就像考虑我们多次检查爱丽丝,看看她是否准备好了,我们每次都登录。因此,每当她将“准备就绪”变为 True 时,Apples 的值对她来说保持不变,但可能会有多行,因为它被记录的次数未知 - 比如 (Alice - False - 2) --> (Alice - True - 5) --> (爱丽丝 - 真 - 5)。另外,有没有办法将结果与另一列分组?假设我有另一个名为“Class”的列,我想按(“Name”,“Class”)分组?
【解决方案2】:

使用np.where 的另一种单行方法。更改False值的符号:

>>> df.assign(Apples=np.where(df['Ready'] == False, -df['Apples'], df['Apples'])) \
      .groupby('Name')['Apples'].sum() \
      .reset_index(name='Collected Apples')

    Name  Collected Apples
0  Alice               4.0
1    Bob               4.0
2  Chris              10.0
3   Dave               0.0

np.where的详细信息:

>>> df.assign(Apples=np.where(df['Ready'] == False, -df['Apples'], df['Apples']))

    Name  Ready  Apples
0  Alice  False    -1.0
1    Bob  False    -3.0
2  Chris   True    10.0
3  Alice   True     5.0
4    Bob   True     7.0
5   Dave  False     NaN

【讨论】:

  • 不错!可以使用 -> .reset_index(name='Collected Apples') 而不是单独的 renamereset_index 步骤。
猜你喜欢
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 2013-08-05
  • 2020-09-09
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
相关资源
最近更新 更多