Получить средневзвешенный столбец сводных данных в новом pandas кадре данных из существующего кадра данных на основе другого идентификатора столбца. - PullRequest
1 голос
/ 19 апреля 2020

Несколько похожий вопрос на предыдущий вопрос, который у меня был здесь: Получить столбцы сводных данных в новом pandas кадре данных из существующего кадра данных на основе другого идентификатора столбца Однако вместо того, чтобы просто брать сумму точек данных, Я хотел бы получить средневзвешенное значение в дополнительной колонке. Я повторю и перефразирую вопрос:

Я хочу суммировать данные в фрейме данных и добавить новые столбцы в другой фрейм данных. Мои данные содержат квартиры с идентификационным номером, а также поверхности и значения U для каждой комнаты в квартире. Что мне нужно, так это иметь информационный фрейм, который суммирует это и дает мне общее поверхностное и поверхностно-взвешенное среднее значение U для каждой квартиры. Для исходного кадра данных существует три условия:

Три условия:

  • кадр данных может содержать пустые ячейки

  • когда значения поверхности или U-значения равны для всех строк в этом идентификаторе (поэтому все одинаковые значения для одного и того же идентификатора), тогда данные (поверхность, объемы) не суммируются, но передается одно значение / строка в новый итоговый столбец (пример: «ID 4») (поскольку это может быть ошибкой в ​​исходном кадре данных, и общая площадь / объем была вставлена ​​для всех комнат государственным служащим)

  • среднее значение U должно составлять средневзвешенное значение U на поверхности

Исходный фрейм данных 'data':

print(data)
    ID  Surface  U-value
0    2     10.0      1.0
1    2     12.0      1.0
2    2     24.0      0.5
3    2      8.0      1.0
4    4     84.0      0.8
5    4     84.0      0.8
6    4     84.0      0.8
7   52      NaN      0.2
8   52     96.0      1.0
9   95      8.0      2.0
10  95      6.0      2.0
11  95     12.0      2.0
12  95     30.0      1.0
13  95     12.0      1.5

Желаемый вывод из 'df':

print(df)

    ID  Surface  U-value  #-> U-value = surface weighted U-value!; Surface = sum of all surfaces except when all surfaces per ID are the same (example 'ID 4')
0    2     54.0   0.777
1    4     84.0   0.8     #-> as the values are the same for each row of this ID in the original data, the sum is not taken, but only one of the rows is passed (see the second condition)
2   52     96.0   1.0     # -> as one of 2 surface is empty, the corresponding U-value for the empty cell is ignored, so the output here should be the weighted average of the values that have both 'Surface'&'U-value'-values (in this case 1,0)
3   95     68.0   1.47

Код jezrael в справочнике уже отлично работает для суммы (), но как добавить средневзвешенное значение U '-вместе с этим? Я действительно понятия не имею,. Среднее можно установить с помощью функции mean () вместо sum (), но средневзвешенного значения ..?

import pandas as pd
import numpy as np

df = pd.DataFrame({"ID": [2,4,52,95]})    

data = pd.DataFrame({"ID": [2,2,2,2,4,4,4,52,52,95,95,95,95,95],                    
                "Surface": [10,12,24,8,84,84,84,np.nan,96,8,6,12,30,12],     
                "U-value": 
[1.0,1.0,0.5,1.0,0.8,0.8,0.8,0.2,1.0,2.0,2.0,2.0,1.0,1.5]})    
print(data)

cols = ['Surface']
m1 = data.groupby("ID")[cols].transform('nunique').eq(1)
m2 = data[cols].apply(lambda x: x.to_frame().join(data['ID']).duplicated())

df = data[cols].mask(m1 & m2).groupby(data["ID"]).sum().reset_index()
print(df)

1 Ответ

1 голос
/ 19 апреля 2020

Это должно помочь:

data.groupby('ID').apply(lambda g: (g['U-value']*g['Surface']).sum() / g['Surface'].sum())

Чтобы добавить к исходному фрейму данных, не сбрасывайте сначала индекс:

df = data[cols].mask(m1 & m2).groupby(data["ID"]).sum()
df['U-value'] = data.groupby('ID').apply(
    lambda g: (g['U-value'] * g['Surface']).sum() / g['Surface'].sum())
df.reset_index(inplace=True)

Результат:

   ID  Surface   U-value
0   2     54.0  0.777778
1   4     84.0  0.800000
2  52     96.0  1.000000
3  95     68.0  1.470588
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...