【问题标题】:Pandas DataFrame: How to calculate the difference by first row and last row in group?Pandas DataFrame:如何计算组中第一行和最后一行的差异?
【发布时间】:2017-09-16 23:41:45
【问题描述】:

这是我的熊猫数据框:

import pandas as pd
import numpy as np

data = {"column1": [338, 519, 871, 1731, 2693, 2963, 3379, 3789, 3910, 4109, 4307, 4800, 4912, 5111, 5341, 5820, 6003, ...],
         "column2": [NaN, 1, 1, 1, 1, NaN, NaN, 2, 2, NaN, NaN, 3, 3, 3, 3, 3, NaN, NaN], ...}

df = pd.DataFrame(data)
df
>>>      column1  column2
0        338      NaN
1        519      1.0
2        871      1.0
3       1731      1.0
4       2693      1.0
5       2963      NaN
6       3379      NaN
7       3789      2.0
8       3910      2.0
9       4109      NaN
10      4307      NaN
11      4800      3.0
12      4912      3.0
13      5111      3.0
14      5341      3.0
15      5820      3.0
16      6003      NaN
17      ....      ....

column2 中的整数表示column1 中的“组”,例如第 1-4 行是“1”组,第 7-8 行是“2”组,第 11-15 行是“3”组,依此类推。

我想计算每组中第一行和最后一行之间的差异。生成的数据框如下所示:

df
>>>      column1  column2  column3
0        338      NaN      NaN
1        519      1.0      2174
2        871      1.0      2174
3       1731      1.0      2174
4       2693      1.0      2174
5       2963      NaN      NaN
6       3379      NaN      NaN
7       3789      2.0      121
8       3910      2.0      121
9       4109      NaN      NaN
10      4307      NaN      NaN
11      4800      3.0      1020
12      4912      3.0      1020
13      5111      3.0      1020
14      5341      3.0      1020
15      5820      3.0      1020
16      6003      NaN      NaN
17      ....      ....     ...

因为:

2693-519 = 2174
3910-3789 = 121
5820-4800 = 1020

计算column3的“熊猫方式”是什么?不知何故,必须遍历column3,寻找像df.column2 != "NaN" 这样的连续值组。

编辑:我意识到我的示例可能会导致读者假设 column1 中的值只会增加。其实是有区间的,列intervals

df = pd.DataFrame(data)
df
>>>    interval      column1  column2
0      interval1     338      NaN
1      interval1     519      1.0
2      interval1     871      1.0
3      interval1     1731      1.0
4      interval1     2693      1.0
5      interval1     2963      NaN
6      interval1     3379      NaN
7      interval1     3789      2.0
8      interval1     3910      2.0
9      interval1     4109      NaN
10     interval1     4307      NaN
11     interval1     4800      3.0
12     interval1     4912      3.0
13     interval1     5111      3.0
14     interval1     5341      3.0
15     interval1     5820      3.0
16     interval1     6003      NaN
17      ....      ....
18     interval2     12        13
19     interval2     115       13
20     interval2     275       NaN
....

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以先过滤,然后在transform中获取第一个和最后一个值的差异:

    df['col3'] = df[df.column2.notnull()]
                      .groupby('column2')['column1']
                      .transform(lambda x: x.iat[-1] - x.iat[0])
    print (df)
        column1  column2    col3
    0       338      NaN     NaN
    1       519      1.0  2174.0
    2       871      1.0  2174.0
    3      1731      1.0  2174.0
    4      2693      1.0  2174.0
    5      2963      NaN     NaN
    6      3379      NaN     NaN
    7      3789      2.0   121.0
    8      3910      2.0   121.0
    9      4109      NaN     NaN
    10     4307      NaN     NaN
    11     4800      3.0  1020.0
    12     4912      3.0  1020.0
    13     5111      3.0  1020.0
    14     5341      3.0  1020.0
    15     5820      3.0  1020.0
    16     6003      NaN     NaN
    

    EDIT1 由您的新数据:

    df['col3'] = df[df.column2.notnull()]
                      .groupby('column2')['column1']
                      .transform(lambda x: x.iat[-1] - x.iat[0])
    print (df)
         interval  column1  column2    col3
    0   interval1      338      NaN     NaN
    1   interval1      519      1.0  2174.0
    2   interval1      871      1.0  2174.0
    3   interval1     1731      1.0  2174.0
    4   interval1     2693      1.0  2174.0
    5   interval1     2963      NaN     NaN
    6   interval1     3379      NaN     NaN
    7   interval1     3789      2.0   121.0
    8   interval1     3910      2.0   121.0
    9   interval1     4109      NaN     NaN
    10  interval1     4307      NaN     NaN
    11  interval1     4800      3.0  1020.0
    12  interval1     4912      3.0  1020.0
    13  interval1     5111      3.0  1020.0
    14  interval1     5341      3.0  1020.0
    15  interval1     5820      3.0  1020.0
    16  interval1     6003      NaN     NaN
    18  interval2       12     13.0   103.0
    19  interval2      115     13.0   103.0
    20  interval2      275      NaN     NaN
    

    【讨论】:

    • 这仅在column1 中的值增加时才有效吗?我意识到我的例子可能有点误导。见上文。
    • 我认为它也有效。但是有多个组1NaNs 分割,需要单独处理这些组吗?
    • 我认为例如column2 2.01.0 替换
    • 只有一个唯一组1,一组2,等等。interval2 中的组永远不会与interval1 中的组相同
    • 好的,有什么问题吗?需要第一个减去组中的最后一个值吗?你能解释更多吗?
    猜你喜欢
    • 2021-11-19
    • 2019-10-18
    • 2023-01-30
    • 2015-04-03
    • 1970-01-01
    • 2019-05-24
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多