Я пытаюсь сделать несколько кластеров на основе набора видео по продолжительности. У меня есть словарь, в котором ключи - это идентификаторы пользователей, а значения - это список с плавающей точкой (длительность видео), 1 плавание на видео, созданное пользователем.

Пример :

videos_per_user = {
    63: [15.011667, 21.823333, 29.981667, 10.341667, 14.928333, 16.555, 29.976667], 
    64: [5.463333, 14.345, 5.571667, 18.848333]
}

Важное примечание: эти списки не имеют одинаковую длину.

То, что я пытаюсь сделать, это превратить этот Dict до панда Dataframe , на основе эталонного вектора ( бункера ) , так что я могу иметь вектор для каждого пользователя , который содержит количество видео для каждой категории.

Я создал свой категориальный вектор следующим образом: {{Х0}}

Я пытался использовать pd.cut(videos_per_user, bins=bins, right=True), но я получаю соответствующую категорию для каждой продолжительности, пока пытаюсь получить что-то вроде: [0,0,2,2,3,0]

Есть идеи ? Я не нашел подобных ситуаций в Интернете, но, возможно, потому что я не знаю, как правильно сформулировать мою проблему.

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

1
Beinje 24 Июн 2019 в 16:28

3 ответа

Лучший ответ

searchsorted и bincount

b = np.arange(5, 30, 5)
# array([ 5, 10, 15, 20, 25])

ОБРАТИТЕ ВНИМАНИЕ: minlength гарантирует, что все массивы будут одинаковой длины. Тем не менее, он должен быть установлен на фактическое количество категорий, которые вы ожидаете иметь. Это может измениться, если ваши фактические настройки не совсем такие, как описано в вопросе.

pd.DataFrame({
    user: np.bincount(b.searchsorted(durations), minlength=len(b) + 1)
    for user, durations in videos_per_user.items()
})

   63  64
0   0   0
1   0   2
2   2   1
3   2   1
4   1   0
5   2   0

value_counts и cut

pd.DataFrame({
    user: pd.value_counts(pd.cut(durations, bins))
    for user, durations in videos_per_user.items()
})

          63  64
(0, 5]     0   0
(5, 10]    0   2
(10, 15]   2   1
(15, 20]   2   1
(20, 25]   1   0
(25, 30]   2   0
1
piRSquared 24 Июн 2019 в 15:16

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

df = pd.DataFrame([(k,a) for k,v in videos_per_user.items() 
                         for a in v], 
                  columns=('user', 'val'))

# cut by bins
df['cat'] = pd.cut(df.val, bins=bins)

# pivot to get the data
df.pivot_table(index='user', columns='cat', aggfunc='count')

Выход:

         val                                    
cat  (5, 10] (10, 15] (15, 20] (20, 25] (25, 30]
user                                            
63       NaN      2.0      2.0      1.0      2.0
64       2.0      1.0      1.0      NaN      NaN
1
Quang Hoang 24 Июн 2019 в 13:44

Используя pd.cut() вы можете сделать следующее:

pd.cut(videos_per_user, 6)

0
Mohamed Abduljawad 24 Июн 2019 в 13:53