#python #pandas
#python #pandas
Вопрос:
Допустим, у меня есть фрейм данных, в котором есть столбец, подобный этому:
Weight
1
1
0.75
0.5
0.25
0.5
1
1
1
1
Я хочу создать две ячейки и добавить столбец в свой фрейм данных, который показывает, в какой ячейке находится каждая строка, но я не хочу привязывать наблюдения (т. Е. Первые 5 наблюдений попали в ячейку 1, а последние пять — в ячейку 2). Вместо этого я хочу создать ячейку таким образом, чтобы сумма весов для каждой ячейки была равна или как можно ближе к равной, насколько это возможно, без изменения порядка столбца.
Итак, я хочу, чтобы результат был
Weight I want Not this
1 1 1
1 1 1
0.75 1 1
0.5 1 1
0.25 1 1
0.5 1 2
1 2 2
1 2 2
1 2 2
1 2 2
Есть ли что-то встроенное в Pandas, которое уже делает это, или кто-нибудь может поделиться какими-либо идеями о том, как это сделать? Спасибо!
Ответ №1:
Это должно сделать это:
df = pd.DataFrame(
{'Weight': [1, 1, 0.75, 0.5, 0.25, 0.5, 1, 1, 1, 1]})
weight_sum = df.Weight.sum()
df['bin'] = 1
df.loc[df.Weight.cumsum() > weight_sum / 2, 'bin'] = 2
print(df)
Вывод:
Weight bin
0 1.00 1
1 1.00 1
2 0.75 1
3 0.50 1
4 0.25 1
5 0.50 1
6 1.00 2
7 1.00 2
8 1.00 2
9 1.00 2
Комментарии:
1. Ах, это лучше, чем мой подход. Также
df['bin'] = np.where(df.Weight.cumsum() > weight_sum / 2, 2, 1]
.
Ответ №2:
Вы могли бы использовать pd.cut
в cumsum
Weights
столбце.
df = pd.DataFrame({'Weight' : [1, 1, 0.75, 0.5, 0.25, 0.5, 1, 1, 1, 1]})
s = df['Weight'].sum()
pd.cut(df['Weight'].cumsum(), [-1, s/2, s], labels=[1,2])
Для s = 8
этого по умолчанию создаются группы (-1, 4]
и (4, 8]
. (Это математическое обозначение — значение точно 4
будет включено в первую группу)
Вы могли бы выбрать по-другому и поместить значение точно 4
во вторую группу, указав right = False
и скорректировав границы, что дает вам группы [0, 4)
и [4, 9)
pd.cut(df['Weight'].cumsum(), [0, s/2, s 1], labels=[1,2], right=False)
-1
И s 1
предназначены для указания того, что значение точно 0
или соответственно 8
все еще должно быть в этой группе.