Я борюсь с такой задачей: мне нужно дискретировать значения в столбце из фрейма данных, с определением бункеров на основе значения в другом столбце.pandas - binning с определениями бункеров на основе значения в другом столбце
Для минимального рабочего примера, позволяет определить простой dataframe:
import pandas as pd
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,'B' : np.random.randn(12)})
dataframe выглядит следующим образом:
A B
0 one 2.5772143847077427
1 one -0.6394141654096013
2 two 0.964652049995486
3 three -0.3922889559403503
4 one 1.6903991754896424
5 one 0.5741442025742018
6 two 0.6300564981683544
7 three 0.9403680915507433
8 one 0.7044433078166983
9 one -0.1695006646595688
10 two 0.06376190217285167
11 three 0.277540580579127
Теперь я хотел бы представить столбец C
, который будет содержать бункер с разными ячейками для каждого из значений в колонке A
, то есть:
(-10,-1,0,1,10)
дляA == 'one'
,(-100,0,100)
дляA == 'two'
,(-999,0,1,2,3)
дляA == 'three'
.
Желаемый результат:
A B C
0 one 2.5772143847077427 (1, 10]
1 one -0.6394141654096013 (-1, 0]
2 two 0.964652049995486 (0, 100]
3 three -0.3922889559403503 (-999, 0]
4 one 1.6903991754896424 (1, 10]
5 one 0.5741442025742018 (0, 1]
6 two 0.6300564981683544 (0, 100]
7 three 0.9403680915507433 (0, 1]
8 one 0.7044433078166983 (0, 1]
9 one -0.1695006646595688 (-1, 0]
10 two 0.06376190217285167 (0, 100]
11 three 0.277540580579127 (0, 1]
Я попытался с помощью pd.cut
или np.digitize
с различными комбинациями map
, apply
, но безуспешно.
В настоящее время я достижение результата путем разделения кадра и применяя pd.cut
каждого подмножество по отдельности, а затем объединять, чтобы получить кадр обратно, как это:
values_in_column_A = df['A'].unique().tolist()
bins = {'one':(-10,-1,0,1,10),'two':(-100,0,100),'three':(-999,0,1,2,3)}
def binnize(df):
subdf = []
for i in range(len(values_in_column_A)):
subdf.append(df[df['A'] == values_in_column_A[i]])
subdf[i]['C'] = pd.cut(subdf[i]['B'],bins[values_in_column_A[i]])
return pd.concat(subdf)
Это работает, но я не думаю, что это достаточно изящна, я также ожидаю некоторых проблем с производительностью или памятью в производстве, когда у меня будут кадры с миллионами строк. Говоря прямо, я думаю, это можно было бы сделать лучше.
Я wolud признателен за любую помощь или идеи ...
Он работает, но очень медленный (более 50 раз медленнее) ... Для DataFrame с 12k строками: 'timeit df ['C'] = df.apply (func, axis = 1)', result: '1 петли, лучше всего 3: 4,75 с за цикл' Для сравнения: 'timeit df2 = binnize (df)', result '10 loop, best of 3: 95.6 ms per loop' ... –
Я предполагаю, что это может произойти из факт, что 'pd.cut' оптимизирован для работы с столбцами, а не в одиночных рядах ... –
Справа, кажется, что булевские индексирование и расчет по столбцам работают намного быстрее, чем операции с строкой ... –