панды создают квантили для столбца, взвешенного по другому столбцу - PullRequest
0 голосов
/ 02 июля 2018

У меня есть df, как

df= pd.DataFrame({'v': [100, 300, 200, 900, 100, 400, 300, 300, 800, 1100], 's':[1.1, 2.7, 0.87, 1.6, 3.2, 0.2, 1.1, 0.3, 1.2, 1.3]})


    s       v
0   1.10    100
1   2.70    300
2   0.87    200
3   1.60    900
4   3.20    100
5   0.20    400
6   1.10    300
7   0.30    300
8   1.20    800
9   1.30    1100

Я хочу получить квантили, почти похожие на

pd.qcut(df["s"], 3,labels=[-1, 0, 1])

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

Что-то вроде

df= pd.DataFrame({'v': [100, 300, 200, 900, 100, 400, 300, 300, 800, 1100], 's':[1.1, 2.7, 0.87, 1.6, 3.2, 0.2, 1.1, 0.3, 1.2, 1.3] ,\
              'c': [-1, 1, -1, 1, 1, -1, -1, -1, 0, 0]})


   c    s   v
0   -1  1.10    100
1   1   2.70    300
2   -1  0.87    200
3   1   1.60    900
4   1   3.20    100
5   -1  0.20    400
6   -1  1.10    300
7   -1  0.30    300
8   0   1.20    800
9   0   1.30    1100

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

1 Ответ

0 голосов
/ 02 июля 2018

Это решение довольно ужасно, если у вас большой фрейм данных, но здесь есть кое-что отличное и более простое от вашего решения (что приятно):

pd.qcut(np.concatenate([[s]*v for s,v in zip(df.s, df.v)]), 3, labels=[-1,0,1])

Вы можете проверить с помощью cumsum на v, прежде чем ваш компьютер взорвется раньше ...

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