#python #dataframe #dask
#python #фрейм данных #dask
Вопрос:
У меня есть фрейм данных dask, подобный приведенному ниже.
> print(df_user_preferences)
user_id food_id
int64 int64 int64
...
Этот фрейм данных представляет отношение «Многие ко многим» между user
и food
.
Существуют также два фрейма данных, df_users
и df_foods
, и это основные данные пользователей и продуктов питания.
И теперь я хочу получить фрейм данных, как показано ниже.
# index is user_id.
> print(df_spread_user_preferences)
food_1 food_2 food_3 food_4 ...
int64 boolean boolean boolean boolean ...
...
Эти столбцы с префиксом, food_
заканчивающимся на food_id
, и их значения представляют отношение между user
и food
.
Я пробовал приведенный ниже код, но это слишком медленно. Как я могу улучшить этот код для более эффективной работы?
df_spread_user_preferences = df_users.assign(**{
f"food_{food_id}": lambda df, food_id: df.apply(
lambda row, food_id: len(df_user_preferences[(
df_user_preferences.food_id == food_id
) amp; (
df_user_preferences.user_id == row.name
)]) > 0,
axis=1,
meta='boolean',
food_id=food_id
) for _, food_id in df_foods.index.to_series().iteritems()
}).drop(df_users.columns)
Ответ №1:
df_users = pd.DataFrame({'user_id': [1,2]})
df_foods = pd.DataFrame({'food_id': [11,22,33,44]})
df_user_preferences = pd.DataFrame({'user_id' : [1,1], 'food_id' : [11,22]})
# Create a dataframe with columns user_ids and all food_ids.
# All food_ids of all the users are assigned False
df_spread_user_preferences = pd.DataFrame({
**{'user_id': df_users['user_id']},
**{"food_{0}".format(i):False for i in df_foods['food_id']}})
# Find the food preference of the users and create a list
foods = df_user_preferences.groupby(['user_id'])['food_id'].apply(list).apply(
lambda x: ["food_{0}".format(i) for i in x]).reset_index()
# For each user get the preference list and reset them to True
for _, r in foods.iterrows():
df_spread_user_preferences.loc[
df_spread_user_preferences['user_id'] == r['user_id'], r['food_id']] = True
print (df_spread_user_preferences)
food_11 food_22 food_33 food_44 user_id
0 True True False False 1
1 False False False False 2
Вы можете присвоить индексу значение user_id с помощью df_spread_user_preferences.set_index('user_id')