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

Я хочу суммировать данные в фрейме данных и добавить новые столбцы в другой фрейм данных. Мои данные содержат квартиры с ID-номером, а также значения поверхности и объема для каждой комнаты в квартире. То, что я хочу, это иметь информационный блок, который суммирует это и дает мне общую поверхность и объем на квартиру. Существует два условия для исходного кадра данных:

Two conditions:
- the dataframe can contain empty cells
- when the values of surface or volume are equal for all of the rows within that ID 
(so all the same values for the same ID), then the data (surface, volumes) is not 
summed but one value/row is passed to the new summary column (example: 'ID 4')(as 
this could be a mistake in the original dataframe and the total surface/volume was 
inserted for all the rooms by the government-employee)

Исходный кадр данных 'data':

print(data)

    ID  Surface  Volume
0    2     10.0    25.0
1    2     12.0    30.0
2    2     24.0    60.0
3    2      8.0    20.0
4    4     84.0   200.0
5    4     84.0   200.0
6    4     84.0   200.0
7   52      NaN     NaN
8   52     96.0   240.0
9   95      8.0    20.0
10  95      6.0    15.0
11  95     12.0    30.0
12  95     30.0    75.0
13  95     12.0    30.0

Требуемый вывод из 'df' :

print(df)
    ID  Surface  Volume
0    2     54.0   135.0
1    4     84.0   200.0  #-> 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   240.0
3   95     68.0   170.0

Пробный код:

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],
                 
                 "Volume":  [25,30,60,20,200,200,200,np.nan,240,20,15,30,75,30]})


print(data)




#Tried something, but no idea how to do this actually:

df["Surface"] = data.groupby("ID").agg(sum)

df["Volume"] = data.groupby("ID").agg(sum)
print(df)

1 Ответ

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

Здесь необходимо 2 условия - сначала проверить, уникальны ли значения для групп для каждого столбца отдельно на GroupBy.transform и DataFrameGroupBy.nunique и сравнить на eq на равное с 1, а затем второе условие - он использовал DataFrame.duplicated для каждого столбца со столбцом ID.

Цепочка обеих масок & для побитового AND и перераспределение соответствующих значений на NaN s на DataFrame.mask и последний агрегат sum:

cols = ['Surface','Volume']
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)
   ID  Surface  Volume
0   2     54.0   135.0
1   4     84.0   200.0
2  52     96.0   240.0
3  95     68.0   170.0

Если нужны новые столбцы, заполненные значениями суммарной суммы, используйте GroupBy.transform:

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

data[cols] = data[cols].mask(m1 & m2).groupby(data["ID"]).transform('sum')
print(data)
    ID  Surface  Volume
0    2     54.0   135.0
1    2     54.0   135.0
2    2     54.0   135.0
3    2     54.0   135.0
4    4     84.0   200.0
5    4     84.0   200.0
6    4     84.0   200.0
7   52     96.0   240.0
8   52     96.0   240.0
9   95     68.0   170.0
10  95     68.0   170.0
11  95     68.0   170.0
12  95     68.0   170.0
13  95     68.0   170.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...