【问题标题】:python pandas multiindex subtract rows with matching level 1 indexpython pandas multiindex减去具有匹配级别1索引的行
【发布时间】:2018-12-16 00:03:50
【问题描述】:

熊猫数据框:

构造函数:

iterables = [[date(2018,5,31),date(2018,6,26),date(2018,6,29),date(2018,7,1)], 
['test1','test2']]
indx = pd.MultiIndex.from_product(iterables, names=['date','tests'])
col = ['tests_passing', 'tests_total']
data = np.array([[834,3476],[229,256],[1524,1738],[78,144],[1595,1738],[78,144],[1595,1738],[142,144]])
df = pd.DataFrame(data, index=indx, columns=col)
df = df.assign(tests_remaining= df['tests_total'] - df['tests_passing'])

数据框:

                 tests_passing  tests_total  tests_remaining
date       tests                                             
2018-05-31 test1            834         3476             2642
           test2            229          256               27
2018-06-26 test1           1524         1738              214
           test2             78          144               66
2018-06-29 test1           1595         1738              143
           test2             78          144               66
2018-07-01 test1           1595         1738              143
           test2            142          144                2

此数据由多个测试测量值(test1、test2、...等)组成,每个测量值都是在某个日期收集的。 我想在这个数据框中创建一个名为“progress”的新列,它通常会选择所有日期中 test = 唯一测试(例如 test1)的所有行,并在 date0 处减去该行的“tests_remaining”列值与下一个date1,date2,...等处的行值基本上是: df.loc[(date0,test0),'progress'] = df.loc[(date0,test0),'tests_remaining']-df.loc[(date1,test0),'tests_remaining] (有一个例外,第一个日期的进度值为 0,因为它是第一个收集的日期)。

所需的输出将如下所示:

                 tests_passing  tests_total  tests_remaining  progress
date      tests                                                       
5/31/2018 test1            834         3476             2642         0
          test2            229          256               27         0
6/26/2018 test1           1524         1738              214      2428
          test2             78          144               66       -39
6/29/2018 test1           1595         1738              143        71
          test2             78          144               66         0
7/1/2018  test1           1595         1738              143         0
          test2            142          144                2        64

到目前为止,我已经能够使用带有切片的 loc[] 一次选择一个测试并将此计算作为结果 pandas Series 执行,但是如果不指定测试,我通常无法在所有测试中执行此操作在拆分中明确命名。这对我来说不是一个合理的解决方案,因为在真实数据中有数百个测试。

All = slice(None)
df_slice = df.loc[(All,'test1'),'tests_remaining']
sub = df_slice.diff(periods=-1).shift(1).fillna(0);sub

date        tests
2018-05-31  test1       0.0
2018-06-26  test1    2428.0
2018-06-29  test1      71.0
2018-07-01  test1       0.0
Name: tests_remaining, dtype: float64

是否有更符合 pandas 习惯的方法来创建所需的列?

提前感谢您的帮助!

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    你可以groupby水平测试并做diff

    df.groupby(level='tests').tests_remaining.diff().mul(-1)
    Out[662]: 
    date        tests
    2018-05-31  test1       NaN
                test2       NaN
    2018-06-26  test1    2428.0
                test2     -39.0
    2018-06-29  test1      71.0
                test2      -0.0
    2018-07-01  test1      -0.0
                test2      64.0
    Name: tests_remaining, dtype: float64
    

    【讨论】:

    • 感谢您的解决方案。这非常有效。我能够通过以下次要代码更新将新列附加到我的数据框中:prog_col = df.groupby(level='tests').tests_remaining.diff().mul(-1).fillna(0).clip_lower(0) prog_col.name = 'progress' df = pd.concat([df,prog_col], axis=1)
    猜你喜欢
    • 2018-09-11
    • 1970-01-01
    • 2020-05-19
    • 2023-03-10
    • 2019-11-19
    • 2015-07-19
    • 2021-04-14
    • 1970-01-01
    • 2018-12-20
    相关资源
    最近更新 更多