Я сталкивался с этими проблемами довольно часто, поэтому я просто подумал поделиться своими решениями в Pandas.
Решения:
Решение 1:
Использование set_index
для преобразования столбца a
в индекс, затем использование reindex
для изменения порядка, затем использование rename_axis
для изменения имени индекса обратно на a
, затем использование reset_index
преобразовать столбец a
из индекса обратно в столбец:
print(df.set_index('a').reindex(s).rename_axis('a').reset_index('a'))
Решение 2:
Использование set_index
для преобразования столбца a
в индекс, затем используйте loc
для изменения порядка, затем используйте reset_index
для преобразования столбца a
из индекса обратно в столбец:
print(df.set_index('a').loc[s].reset_index())
Решение 3:
Используя iloc
для индексации строк в другом порядке, затем используйте map
, чтобы получить тот порядок, который соответствует df
, чтобы отсортировать его по серии s
:
print(df.iloc[list(map(df['a'].tolist().index, s))])
Решение 4:
Использование pd.DataFrame
для создания нового объекта DataFrame, затем использование sorted
с аргументом key
для сортировки DataFrame b y серия s
:
print(pd.DataFrame(sorted(df.values.tolist(), key=lambda x: s.tolist().index(x[0])), columns=df.columns))
Время:
Время с кодом ниже:
import pandas as pd
from timeit import timeit
df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [100, 200, 300, 400]})
s = pd.Series([1, 3, 2, 4])
def u10_1():
return df.set_index('a').reindex(s).rename_axis('a').reset_index('a')
def u10_2():
return df.set_index('a').loc[s].reset_index()
def u10_3():
return df.iloc[list(map(df['a'].tolist().index, s))]
def u10_4():
return pd.DataFrame(sorted(df.values.tolist(), key=lambda x: s.tolist().index(x[0])), columns=df.columns)
print('u10_1:', timeit(u10_1, number=1000))
print('u10_2:', timeit(u10_2, number=1000))
print('u10_3:', timeit(u10_3, number=1000))
print('u10_4:', timeit(u10_4, number=1000))
Выход:
u10_1: 3.012849470495621
u10_2: 3.072132612502147
u10_3: 0.7498072134665241
u10_4: 0.8109911930595484
У @ Аллен тоже довольно хороший ответ.