На GitHub есть открытый запрос об этом. По сути, вам придется использовать apply
, чтобы обойти это. Я не уверен, влияет ли это на производительность в dask
. Существует еще одна заявка, в которой упоминается проблема и указывается, что она находится в pandas
, но она была открыта в течение некоторого времени.
Это должно быть эквивалентно операции pandas
:
import dask.dataframe as dd
import pandas as pd
import random
df = pd.DataFrame({'a': list(range(10)),
'b': random.choices(['x', 'y'], k=10)})
print("####### PANDAS ######")
print("Initial df")
print(df.head(10))
print("................")
pandas_df = df.copy()
print("Final df")
pandas_df['a'] = pandas_df.groupby(['b'])['a'].apply(lambda x: x.shift(-1))
print(pandas_df.head(10))
print()
print("####### DASK ######")
print("Initial df")
dask_df = dd.from_pandas(df, npartitions=1).reset_index()
print(dask_df.head(10))
print("................")
dask_df['a'] = dask_df.groupby(['b'])['a'].apply(lambda x: x.shift(-1))
print("Final df")
print(dask_df.head(10))
Я, очевидно, не могу протестировать подход в dask
, поскольку альтернативы, похоже, нет. Тем не менее, я могу в pandas
:
import string
import numpy as np
import pandas as pd
df = pd.DataFrame({'a': list(range(100000)),
'b': np.random.choice(list(string.ascii_lowercase), 100000)
})
def normal_way(df):
df = df.groupby(['b'])['a'].shift(-1)
def apply_way(df):
df = df.groupby(['b'])['a'].apply(lambda x: x.shift(-1))
Результаты timeit
:
%timeit normal_way(df)
4.25 ms ± 98 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit apply_way(df)
15 ms ± 446 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)