DASK: есть ли эквивалент numpy.select для dask? - PullRequest
0 голосов
/ 08 октября 2019

Я использую Dask , чтобы загрузить CSV-строку длиной 11 м в кадр данных и выполнить вычисления. Я достиг положения, когда мне нужна условная логика - если это, то это, иначе другое.

Если бы я использовал, например, панд, я мог бы сделать следующее, где используется оператор numpy selectнаряду с массивом условий и результатов. Выполнение этого утверждения занимает около 35 секунд - неплохо, но не здорово:

df["AndHeathSolRadFact"] = np.select(
    [
    (df['Month'].between(8,12)),
    (df['Month'].between(1,2) & df['CloudCover']>30) #Array of CONDITIONS
    ],  #list of conditions
    [1, 1],     #Array of RESULTS (must match conditions)
    default=0)    #DEFAULT if no match

Я надеюсь использовать dask , чтобы сделать это изначально в dask dataframeбез необходимости сначала конвертировать мой dask кадр данных в кадр данных pandas, а затем снова обратно. Это позволяет мне: - использовать многопоточность - использовать фрейм данных, который больше доступного оперативной памяти - потенциально ускорить результат.

Пример CSV

Location,Date,Temperature,RH,WindDir,WindSpeed,DroughtFactor,Curing,CloudCover
1075,2019-20-09 04:00,6.8,99.3,143.9,5.6,10.0,93.0,1.0 
1075,2019-20-09 05:00,6.4,100.0,93.6,7.2,10.0,93.0,1.0
1075,2019-20-09 06:00,6.7,99.3,130.3,6.9,10.0,93.0,1.0
1075,2019-20-09 07:00,8.6,95.4,68.5,6.3,10.0,93.0,1.0
1075,2019-20-09 08:00,12.2,76.0,86.4,6.1,10.0,93.0,1.0

Полный код для минимального жизнеспособного образца

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

# Dataframes implement the Pandas API
import dask.dataframe as dd

from timeit import default_timer as timer
start = timer()
ddf = dd.read_csv(r'C:\Users\i5-Desktop\Downloads\Weathergrids.csv')

#Convert back to a Dask dataframe because we want that juicy parallelism
ddf2 = dd.from_pandas(df,npartitions=4)
del [df]

print(ddf2.head())
#print(ddf.tail())
end = timer()
print(end - start)

#Clean up remaining dataframes
del [[ddf2]

Ответы [ 2 ]

0 голосов
/ 09 октября 2019

Итак, ответ, который я смог найти, был наиболее эффективным:

#Create a helper column where we store the value we want to set the column to later. 
ddf['Helper'] = 1

#Create the column where we will be setting values, and give it a default value
ddf['AndHeathSolRadFact'] = 0

#Break the logic out into separate where clauses. Rather than looping we will be selecting those rows 
#where the conditions are met and then set the value we went. We are required to use the helper 
#column value because we cannot set values directly, but we can match from another column. 
#First, a very simple clause. If Temperature is greater than or equal to 8, make 
#AndHeathSolRadFact equal to the value in Helper
#Note that at the end, after the comma, we preserve the existing cell value if the condition is not met
ddf['AndHeathSolRadFact'] = (ddf.Helper).where(ddf.Temperature >= 8, ddf.AndHeathSolRadFact)

#A more complex example 
#this is the same as the above, but demonstrates how to use a compound select statement where 
#we evaluate multiple conditions and then set the value.
ddf['AndHeathSolRadFact'] = (ddf.Helper).where(((ddf.Temperature == 6.8) & (ddf.RH == 99.3)), ddf.AndHeathSolRadFact)

Я новичок в этом, но я предполагаю, что этот подход считается векторизованным. Это в полной мере использует массив и оценивает очень быстро. Добавление нового столбца, заполнение его 0, оценка обоих операторов выбора и замена значений в целевых строках только добавили 0,2 с ко времени обработки в наборе данных 11-метровой строки с npartitions = 4.

Прежние и подобные подходы в пандах занимали 45 секунд или около того.

Осталось только удалить вспомогательный столбец, как только мы закончим. В настоящее время я не уверен, как это сделать.

0 голосов
/ 08 октября 2019

Звучит так, как будто вы ищете dd.Series.where

...