Панды группировки и объединения строк - PullRequest
0 голосов
/ 15 мая 2018

У меня большой DataFrame, который выглядит следующим образом:

+----------------------------------------------------------+
| Date           Category        Location       ImpactRate |
+----------------------------------------------------------+
| 2018-04-22     Outage          MT               0.05194  |
| 2018-04-22     Outage          ND               0.02552  |
| 2018-04-22     Outage          SD               0.09962  |
| 2018-04-24     Transport       TX               0.03111  |
+----------------------------------------------------------+

Я пытаюсь создать следующий вывод:

+-----------------------------------------------------------------------------------+
|   Date           Category        ImpactRate        Break Down             |
+-----------------------------------------------------------------------------------+
| 2018-04-22     Outage          0.17708           MT (29.3%) SD (14.4%) ND (56.3%) |
| 2018-04-24    Transport       0.03111            TX (100.0%)                      |
+-----------------------------------------------------------------------------------+

Первая попытка -GroupBy

grouped_df = df.groupby('Date')['ImpactRate'].apply(list).apply(pd.Series).rename(columns=df['Location'])'

Это создает DataFrame, который будет содержать NaN, где нет каждого местоположения, и создает дополнительные столбцы, требующие форматирования.

Вторая попытка - цикл с использованиемitertuples ():

r = []
for item in df.itertuples():
    temp_x = df.loc[((df['Category'] == item[2]) & (df['Date'] == item[1]))
    for i in range(temp_x.shape[0]):
        r.append(temp_x['ImpactRate'].iloc[i])

Это создает один гигантский список ImpactRate - который возвращает меня к исходной точке.

Я не знаю достаточно, чтобы понять, как решить эту проблему.Я предполагаю, что я должен составить список в списке для каждой итерации, но я продолжаю идти кругами.Как я могу достичь этого результата самым питоническим способом?(Пожалуйста, объясните, чтобы я мог учиться!)

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Я не очень хорошо себя чувствую по этому поводу ... ну да ладно.

d = pd.Series(
    df.ImpactRate.values,
    [list(zip(df.Date, df.Category)), df.Location],
    name='Impact Rate'
)

s = d.sum(level=0)
t = d.div(s, level=0).rename('Break Down')

f = lambda t: ' '.join(f'{l} ({v*100:0.2f}%)' for (_, l), v in t.items())

pd.DataFrame(pd.concat(
    [s, t.groupby(level=0).apply(f)], axis=1
).to_dict()).rename_axis(['Date', 'Category']).reset_index()

         Date   Category                           Break Down  Impact Rate
0  2018-04-22     Outage  MT (29.33%) ND (14.41%) SD (56.26%)      0.17708
1  2018-04-24  Transport                         TX (100.00%)      0.03111
0 голосов
/ 15 мая 2018

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

import pandas as pd

df = pd.DataFrame({'Date': ['2018-04-22', '2018-04-22', '2018-04-22', '2018-04-24'],
                   'Category': ['Outage', 'Outage', 'Outage', 'Transport'],
                   'Location': ['MT', 'ND', 'SD', 'TX'],
                   'ImpactRate': [0.05194, 0.02552, 0.09962, 0.03111]})

# apply ratio
df['Total'] = df.groupby(['Date', 'Category'])['ImpactRate'].transform('sum')
df['ImpactRate'] /= df['Total']

# create tuple column
df['Breakdown'] = list(zip(df.Location, df.ImpactRate))

# groupby to list
df = df.groupby(['Category', 'Date', 'Total'])['Breakdown'].apply(list).reset_index()

Результат:

print(df)

    Category        Date    Total  \
0     Outage  2018-04-22  0.17708   
1  Transport  2018-04-24  0.03111   

                                           Breakdown  
0  [(MT, 0.293313756494), (ND, 0.144115653942), (...  
1                                        [(TX, 1.0)]  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...