Разделение кадра данных Python Dask на основе значения столбца - PullRequest
0 голосов
/ 10 января 2019

Я полный новичок в Python Dask (небольшой опыт работы с пандами). У меня есть большой Dask Dataframe (~ 10–20 миллионов строк), который я должен разделить на основе уникального значения столбца.

Например, если у меня есть следующий Dataframe со столбцами C1 до Cn (извините, я не знаю, как создать правильную таблицу в stackoverflow), и я хочу создать подмножества Dataframes для каждого уникального значения столбца C2

Base Dataframe:


|Ind| C1 | C2 |....| Cn |
|-----------------------|
| 1 |val1| AE |....|time|
|-----------------------|
| 2 |val2| FB |....|time|
|-----------------------|
|...|....| .. |....| ...|
|-----------------------|
| n |valn| QK |....|time|
Subset Dataframes to be created:

Subset 1:

|Ind| C1 | C2 |....| Cn |
|-----------------------|
| 1 |val1| AE |....|time|
|-----------------------|
| 2 |val2| AE |....|time|
|-----------------------|
|...|....| .. |....| ...|
|-----------------------|
| n |valn| AE |....|time|

Subset 2

|Ind| C1 | C2 |....| Cn |
|-----------------------|
| 1 |val1| FB |....|time|
|-----------------------|
| 2 |val2| FB |....|time|
|-----------------------|
|...|....| .. |....| ...|
|-----------------------|
| n |valn| FB |....|time|


and so on.

Мой текущий подход заключается в получении всех уникальных значений C2 и итеративной фильтрации базового кадра данных для каждого из этих значений. Но это занимает много времени. Сейчас я изучаю, как я могу улучшить этот процесс, но я был бы очень признателен, если бы кто-нибудь из вас дал мне несколько советов.

1 Ответ

0 голосов
/ 10 января 2019

Мне кажется, что вы можете получить одинаковые подмножества с groupby в pandas и dask.

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

N = 5
rndm2 = lambda :"".join(np.random.choice(list(string.ascii_lowercase), 2))
df_sample = pd.DataFrame({"C1":np.arange(N),
                          "C2":[rndm2() for i in range(N)],
                          "C3":np.random.randn(N)})

M = 2
df = pd.concat([df_sample for i in range(M)], ignore_index=True)
df["C4"] =  np.random.randn(N*M)

Здесь я просто печатаю print(list(df.groupby("C2"))[0][1]), чтобы показать вам, что у вас внутри каждой группы:

   C1  C2        C3        C4
3   3  bx  0.668654 -0.237081
8   3  bx  0.668654  0.619883

Если вам нужно, чтобы диск был хорошо разбит на разделы, вы можете сделать следующее

ddf = dd.from_pandas(df, npartitions=4)
ddf.to_parquet("saved/", partition_on=["C2"])

# You can check that the parquet files
# are in separated folder as
! ls saved/ # If you are on Linux

'C2=iw'  'C2=jl'  'C2=qf'  'C2=wy'  'C2=yr'   _common_metadata

Теперь, если вы хотите выполнить какое-либо вычисление с использованием этих групп, вы можете применить свою функцию fun с map_partitions, заботясь о выходной мета.

df = dd.read_parquet("saved/")
out = df.map_partitions(lambda x: fun(x)).compute() # you should add your output meta
...