Средневзвешенная с несколькими весами и группами питона - PullRequest
0 голосов
/ 11 октября 2019

Я новичок в Python и пытаюсь улучшить свой код - поэтому я был бы признателен за несколько советов о том, как повысить эффективность следующего.

У меня есть следующий набор данных:

petdata = {
    'animal' : ['dog', 'cat', 'fish'],
    'male_1' : [0.57, 0.72, 0.62],
    'female_1' : [0.43, 0.28, 0.38],
    'age_01_1': [0.10,0.16,0.15],
    'age_15_1':[0.17,0.29,0.26],
    'age_510_1':[0.15,0.19,0.19],
    'age_1015_1':[0.18,0.16,0.17],
    'age_1520_1':[0.20,0.11,0.12],
    'age_20+_1':[0.20,0.09,0.10],
    'male_2' : [0.57, 0.72, 0.62],
    'female_2' : [0.43, 0.28, 0.38],
    'age_01_2': [0.10,0.16,0.15],
    'age_15_2':[0.17,0.29,0.26],
    'age_510_2':[0.15,0.19,0.19],
    'age_1015_2':[0.18,0.16,0.17],
    'age_1520_2':[0.20,0.11,0.12],
    'age_20+_2':[0.20,0.09,0.10],
    'weight_1': [10,20,30],
    'weight_2':[40,50,60]
}

df = pd.DataFrame(petdata) 

Я хочу рассчитать средневзвешенное значение для животных в моем наборе данных, используя weight_1 для всех переменных, заканчивающихся на «_1» и weight_2 для всехпеременные, которые заканчиваются на «_2».

В настоящее время я делаю это следующим образом:

df['male_wav_1']=np.nansum((df['male_1']*df['weight_1'])/df['weight_1'].sum())
df['female_wav_1']=np.nansum((df['female_1']*df['weight_1'])/df['weight_1'].sum())


df['male_wav_2']=np.nansum((df['male_2']*df['weight_2'])/df['weight_2'].sum())
df['female_wav_2']=np.nansum((df['female_2']*df['weight_2'])/df['weight_2'].sum())

И это для каждого отдельного столбца в моем фрейме данных (т.е. age_01_1_wav, age_15_1_wav ...) Я понимаю, что это не такочень аккуратно, поэтому кто-нибудь может дать мне несколько советов о том, как улучшить процесс?

Я пытался:

  • изменить данные с широкого на длинный
  • определить функцию для средневзвешенного значения

НоЯ был неудачным с обоими. Проблема не в изменении формы, я могу это сделать, но у меня нет ясности относительно того, как применять разные веса к различным группам, которые у меня есть в моих данных.

Большое спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 11 октября 2019

Во-первых, я предполагаю, что столбец «животные» - это ваш индекс, поэтому для того, чтобы выглядеть как таблица, я сделал его индексом:

import pandas as pd
import numpy as np
petdata = {
    # All of your data ^ above
}

df = pd.DataFrame(petdata)  # Creates the DF from your dictionary
df.set_index('animal',inplace=True) # Sets the 'animal' column as the index

Я бы начал с разбивки вашего DataFrameна две части: df_1 и df_2

# Uses list comprehension to create a list of all column names with a given string
# in the name, and uses this list to get a sub-DataFrame for each
df_1 = df[[name for name in df.columns if '_1' in name]]
df_2 = df[[name for name in df.columns if '_2' in name]]

Вместо того, чтобы создавать новую серию (столбец) в вашем DataFrame для каждой существующей серии, я бы лучше создал новую строку, которая является средневзвешенным (wav) для каждого столбца. Это будет не так красиво, так как новая строка не будет животным, но индекс «wav» будет в столбце животных.

Создайте два списка взвешенных средних, используя понимание списка и уравнение, в котором вы находились. используя:

wav_1 = [np.nansum(df[col]*df_1['weight_1'])/np.nansum(df_1['weight_1']) for col in df_1.columns]
wav_2 = [np.nansum(df[col]*df_1['weight_2'])/np.nansum(df_1['weight_2']) for col in df_2.columns]

Затем добавьте эти данные в два кадра данных, используя новую метку 'wav':

df_1.loc['wav'] = wav_1
df_2.loc['wav'] = wav_2

Обратите внимание, что в 'wav' - 'weight_x есть ненужные данныекоробка. Это средневзвешенное значение ваших весов.

Добро пожаловать в Python! Надеюсь, это поможет.

0 голосов
/ 11 октября 2019

Вы можете использовать функцию Python zip () для быстрых вычислений.

    petdata = {
        'animal' : ['dog', 'cat', 'fish'],
        'male_1' : [0.57, 0.72, 0.62],
        'age_20+_2':[0.20,0.09,0.10],
        'weight_1': [10,20,30],
        'weight_2':[40,50,60]
    }
weight_1 = petdata.get('weight_1')
male_1 = petdata.get('male_1')
for sales, costs in zip(weight_1, male_1):
    profit =sales * costs / sales
    print(f'Total profit: {profit}')

Total profit: 0.57
Total profit: 0.72
Total profit: 0.62
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...