#python #pandas
#python #pandas
Вопрос:
У меня есть фрейм данных со столбцами и идентификаторами и значениями.
df=
id val
'a' 1
'b' 3
'c' 9
….
У меня есть список (повторяющихся) значений идентификаторов.
i_list=['a','a','a','b']
Мне нужно сопоставить этот список (повторяющихся) значений идентификаторов в соответствующие (повторяющиеся) столбцы значений, используя пары фреймов данных (id, val)
out_desired=[1,1,1,3]
Прямо сейчас я делаю:
out_desired=[df[df.id==curr_id].val.values for curr_id in i_list ]
Как сделать это более эффективным, но в то же время кратким способом?
Ответ №1:
Вы можете попробовать использовать pandas.merge
, поскольку мне кажется, что это быстрее.
df = {'id': ['a', 'b', 'c'], 'value': [1,3,9]}
df = pd.DataFrame(df).set_index('id')
test = ['a', 'b', 'c']*8
%timeit df.merge(pd.DataFrame({'id':test}), left_index=True, right_on='id', how='right')['value'].values
1.32 ms ± 33.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit [df[df.index==curr_id].values for curr_id in test ]
5.81 ms ± 123 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Я считаю, что это дает правильный ответ
Ответ №2:
Если id
s отсортированы по лексике, вы можете использовать Series.searchsorted
:
df.loc[df['id'].searchsorted(i_list), 'val'].to_numpy().tolist()
[1, 1, 1, 3]
Или вы можете установить id
как индекс (работает и для не отсортированных id
):
df.set_index('id').loc[i_list, 'val'].to_numpy().tolist()
# [1, 1, 1, 3]
Если id
столбец не отсортирован, выполните сортировку, а затем выполните описанные выше действия для первого подхода к работе:
print(df)
id val
0 c 1
1 b 3
2 a 9
df_ = df.sort_values(['id'])
df_.loc[df_['id'].searchsorted(i_list), 'val'].to_numpy().tolist()
[1, 1, 1, 3]
Комментарии:
1. Второй подход может быть быстрее @ 00__00__00 установка в качестве индекса
2. Я оставлю вопрос открытым на пару дней, поскольку другие ответы также могут быть полезны
3. Вы проверили, работает ли второй подход быстрее? Я думаю, что это проще и должно быть быстрее @ 00__00__00