python pandas groupby и вычитание столбцов из разных групп

У меня есть датафрейм df1

pid     stat       h1         h2       h3      h4      h5      h6     ...     h20

1        a        3.2        3.5       6.2     7.1    1.2      2.3    ...    3.2
1        b        3.3        1.5       4.2     7.7    4.2      3.5   ...     8.4
1        a        3.1        3.8       2.2     1.1    6.2      5.3   ...     9.2
1        b        3.7        1.2       8.2     4.7    3.2      8.5   ...     2.4
:        :         :          :         :       :      :        :      :      :
2        a        2.2       3.8        6.2     7.3    1.3      4.3   ...     3.2
2        b        4.3       1.3        4.2     5.7    2.2      3.1   ...     2.4
2        a        2.1       3.7        2.4     1.6    6.4      9.3   ...     9.6
2        b        3.8       1.3        8.7     3.7    7.2      8.3   ...     9.4
:        :         :         :          :       :      :        :     :       : 
3        a        2.2       3.8        6.2     7.3     1.3     4.3   ...     3.2
3        b        4.3       1.3        4.2     5.7     2.2     3.1   ...     2.4
3        a        2.1       3.7        2.4     1.6     6.4     9.3   ...     9.6
3        b        3.8       1.3        8.7     3.7     7.2     8.3   ...     9.4
  :      :         :         :          :       :       :        :     :      :

Я хотел бы получить группы, проиндексированные по pid и stat, а затем вычесть h значений group1 из h значений group2 для окончательного dataframe (df2). Этот окончательный кадр данных необходимо переиндексировать с номерами, начинающимися с 0:len(groups) Повторите его итеративно для всех перестановок pid, таких как 1-2, 1-3, 1-4, 2-1, 2-3... и т. д. Мне нужно выполнить другие расчеты в окончательном кадре данных df2 (значения в приведенном ниже df2 не вычитаются точно, а просто представляются)

pid(string)     stat    h1p1-h1p2   h2p1-h2p2   h3p1-h3p2   h4p1-h4p2   h5p1-h5p2   h6p1-h6p2   ...  h20p1-h2p2

   1-2           a        3.2         3.5         6.2         7.1         1.2         2.3        ...      3.2
   1-2           b        3.3         1.5         4.2         7.7         4.2         3.5        ...      8.4
   1-2           a        3.1         3.8         2.2         1.1         6.2         5.3        ...      9.2
   1-2           b        3.7         1.2         8.2         4.7         3.2         8.5        ...      2.4
   1-3      ....

Я посмотрел варианты;

  for (pid, stat), group in df1.groupby(['pid', 'stat']):
      print('pid  = %s Stat =  %s' %(pid, stat))
      print group

это дает мне группы, но я не уверен, как получить доступ к кадрам данных из этого цикла for и использовать его для вычитания из других групп. Также

  df_grouped = df.groupby(['pid', 'stat']).groups()

все еще не уверен, как получить доступ к новому фрейму данных групп и выполнять операции. Я хотел бы знать, можно ли это сделать с помощью groupby или есть ли лучший подход. Заранее спасибо!


person Jagruth    schedule 06.05.2016    source источник


Ответы (1)


Я реализовал генератор и проигнорировал столбец stat, потому что он не отличается ни в одной группе в соответствии с вашим образцом. Пожалуйста, скажите мне, если я сделал это неправильно.

import pandas as pd
from itertools import permutations

def subtract_group(df, col):
    pid = df['pid'].unique()

    # select piece with pid == i
    segment = lambda df, i: df[df['pid'] == i].reset_index()[col]

    for x, y in permutations(pid, 2):
        result_df = pd.DataFrame(segment(df, x) - segment(df, y))

        # rename columns
        result_df.columns=["%sp%d-%sp%d" % (c, x, c, y) for c in col]

        # insert pid column
        result_df.insert(0, 'pid', '-'.join([str(x), str(y)]))

        yield result_df

Вы можете протестировать его с помощью:

# column name in your case
columns = ['h' + str(i+1) for i in range(20)]

print next(subtract_group(df1, columns))

Надеюсь, поможет.

person Zhenhao Chen    schedule 07.05.2016
comment
Идеальный ответ. Благодарю вас! - person Jagruth; 09.05.2016