Алгоритм для отображения одного категориального распределения на другое? - PullRequest
0 голосов
/ 18 сентября 2018

На днях я столкнулся с тем, что считал простой проблемой: учитывая популяцию организаций (в данном случае компаний), я хочу спроецировать распределение одной категории на другую.Например, здесь представлены две категории:

     60%       40%
|----A1----|---A2---|
|---B1---|----B2----|
    40%       60%

В приведенном выше описании категория A представляет «количество сотрудников», а категория B представляет «годовой объем продаж».Каждая категория представляет собой отдельный способ нарезки / группировки одного и того же населения, поэтому общее количество компаний в категориях «А» равно общему количеству во всех категориях «В».

Поскольку категория А1 больше, чем категория В1,я думаю получить средневзвешенное значение, что-то вроде: «возьмите 2/3 (40% / 60%) от B1 и 1/3 (остаток) от B2».В приведенном выше примере, если B1 - это доход в размере 1500 долларов США, а B2 - 3000 долларов США, то средний показатель по категории A1 составит 2000 долларов США (т.е. (2/3) * 1500 долларов США + (1/3) * 3000 долларов США).А для категории А2 выручка составила бы 3000 долларов.

Черт побери, если бы я смог выяснить, как закодировать это таким образом, чтобы он масштабировался до n категорий и охватывал все ситуации.Подход, который я в итоге использовал, заключался в том, чтобы раздувать каждый фрейм данных по «количеству» (решение, которое я нашел здесь , кстати), присоединиться с использованием индекса строки, а затем взять среднее значение там.Я знаю, что это сводится к проблеме средневзвешенного значения, но я не мог ее решить.

Вот мой пример кода Python / Pandas:

import pandas as pd

d_A = {'Cat_A_Name': ['A1', 'A2'], 'Cat_A_Empl': [2, 5], 'Cat_A_Counts': [60, 40]}
d_B = {'Cat_B_Name': ['B1', 'B2'], 'Cat_B_Rev': [1500, 3000], 'Cat_B_Counts': [40, 60]}

df_A = pd.DataFrame(data=d_A)
df_B = pd.DataFrame(data=d_B)

# For each dataframe, do a row-expansion by count (and then drop that count column)
df_A = df_A.loc[df_A.index.repeat(df_A['Cat_A_Counts'].astype('int'))].reset_index(drop=True)
df_A.drop({'Cat_A_Counts'}, axis=1, inplace=True)
df_B = df_B.loc[df_B.index.repeat(df_B['Cat_B_Counts'].astype('int'))].reset_index(drop=True)
df_B.drop({'Cat_B_Counts'}, axis=1, inplace=True)

# Then join by index, take the average by Cat_A_Name, and drop duplicate rows
df_All = df_A.join(df_B)
df_All['Avg_Cat_B_Rev'] = df_All.groupby('Cat_A_Name')['Cat_B_Rev'].transform(pd.Series.mean)
df_All.drop_duplicates(subset='Avg_Cat_B_Rev', inplace=True)

print(df_A.head())
print(df_B.head())
print(df_All)

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

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