Как правильно выполнить многоиндексную нарезку на Dask DataFrame? - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь эффективно нарезать два индекса в Dask.

Я пытался использовать .loc на втором уровне, но получаю эту ошибку:

cmb.loc[(slice(0, 1), slice(1, 10))].compute() 
cmb.loc[(slice(0, 1), slice(1.0,20.0))].compute() # (2)

TypeError: cannot do slice indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [1] of <class 'int'>

Вот контекст:

import dask.dataframe as dd
import pandas as pd
import numpy as np

def gen_start_times():
    durations = np.clip(np.random.randn(10) * 2 + 10, 3, 25)
    time_to_next = np.clip(np.random.randn(10) * 1 + 1, 0.01, 5)
    start_plus_pad = durations + time_to_next
    start_times = np.cumsum(start_plus_pad)
    return start_times, durations

channels = range(10)

def create_many_h5_files(files_to_create, nrows=1000000):
    dfs = []
    for c in channels:
        start_times, durations = gen_start_times()
        df = pd.DataFrame({'start_time': start_times,
                           'durations': durations})
        df['channel'] = c
        dfs.append(df)
    dfs_combined = pd.concat(dfs)
    dfs_combined = dfs_combined.set_index(['channel', 'start_time']).sort_index(level=0)
    for file in files_to_create:
        dfs_combined['filename'] = file
        dfs_combined.to_hdf(file, key='/main', format='table')

if __name__ == '__main__':
    to_create = [f'df_{n}.h5' for n in range(8)]
    create_many_h5_files(to_create, nrows=100000)
    cmb = dd.read_hdf(pattern='df_*.h5', key='/main')
    cmb.loc[0].head()

    # Works, but only on first index
    cmb.loc[1].compute()
    cmb.loc[1:2].compute()
    cmb.loc[slice(0,1)].compute()
    cmb.loc[(slice(0, 1))].compute()
    cmb.loc[(slice(0, 1), slice(None))].compute() # (1)

    # Errors
    cmb.loc[(slice(0, 1), slice(1, 10))].compute() 
    cmb.loc[(slice(0, 1), slice(1.0,20.0))].compute() # (2)

    # Keeps the index level, slices on first index again
    cmb.loc[1].loc[1:10].compute()

Это фактические результаты из (1) выше

cmb.loc[(slice(0, 1), slice(None))].compute().head()
                    durations filename
channel start_time                    
0       14.343985   11.167318  df_0.h5
        25.722012    9.012836  df_0.h5
        36.066957   10.266020  df_0.h5
        49.180045   11.974180  df_0.h5
        55.179495    5.989450  df_0.h5

Я хотел бы (2) выше дать мне этот вывод:

cmb.loc[(slice(0, 1), slice(1.0,20.0))].compute().head()
                    durations filename
channel start_time                    
0       14.343985   11.167318  df_0.h5

В идеале, если бы в даске был метод xs, который работал бы точно так же, как в пандах, это немедленно решило бы мои проблемы:

dfs_combined.xs([slice(1, 2), slice(45, 200)],
                    level=['channel', 'start_time'])

1 Ответ

0 голосов
/ 20 февраля 2019

По состоянию на 2019-02-19 фреймы данных Dask не поддерживают Pandas MultiIndex.

...