Если порядок значений в столбцах не важен, преобразуйте каждый столбец в set
для удаления дубликатов, затем в Series
и объедините с помощью concat
:
df1 = pd.concat({k: pd.Series(list(set(v))) for k, v in df.to_dict('l').items()}, axis=1)
Если заказ важен:
df1 = pd.concat({col: pd.Series(df[col].unique()) for col in df.columns}, axis=1)
Производительность 1К уникальных значений в 2К строк :
np.random.seed(2019)
#2k rows
df = pd.DataFrame(np.random.randint(1000, size=(20, 2000))).astype(str)
In [151]: %timeit df.apply(lambda col: col.drop_duplicates().reset_index(drop=True))
1.07 s ± 16.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [152]: %timeit pd.concat({k: pd.Series(list(set(v))) for k, v in df.to_dict('l').items()}, axis=1)
323 ms ± 2.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [153]: %timeit pd.concat({col: pd.Series(df[col].unique()) for col in df.columns}, axis=1)
430 ms ± 4.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Производительность 100 уникальных значений в 2 тыс. Строк
df = pd.DataFrame(np.random.randint(100, size=(20, 2000))).astype(str)
In [155]: %timeit df.apply(lambda col: col.drop_duplicates().reset_index(drop=True))
1.3 s ± 12.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [156]: %timeit pd.concat({k: pd.Series(list(set(v))) for k, v in df.to_dict('l').items()}, axis=1)
544 ms ± 3.37 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [157]: %timeit pd.concat({col: pd.Series(df[col].unique()) for col in df.columns}, axis=1)
654 ms ± 3.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)