首页 > 解决方案 > 创建新列时在 Dask 中高效使用 If Then 场景

问题描述

我有一个大约 11m 行的 csv,我正在读入一个 dask 数据帧。我正在尝试创建一个新列,它是 if/then/else 场景的结果。我在理解如何让它工作时遇到了一些麻烦,同样重要的是让它有效地工作。我是熊猫/dask的新手。

基本上这就是我尝试过的:从创建列事件调用函数。这是我一直在尝试的一个简化示例。

#var1 = 0
#var2 = 10

def find_situation:
    If (var1 == 0 and var2 > 10):
        print("Situation 1")
    elif var1 == 0 and var2 < 10:
        print("Situation 2")
    else:
        print("No Situation")

ddf['situation'] = ddf.apply(find_situation(ddf['ddfvar1'], ddf['ddfvar2']))

这种方法会导致错误消息指出“ValueError:Series 的真值不明确。请使用 a.any() 或 a.all()。” 这些操作的帮助主题读起来像是正在解析的数据行中的任何或所有值,而不是我传递给函数的值?

另外,我读到矢量化要快得多,但我不确定这是否是可以矢量化查询的那种场景?

长版本,我只是试图确定月份列中的值作为起点。真的,我需要转向我在简化示例中所做的复合 if 语句的类型:

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

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

def f(x):
    if x == 9:
        y = 'Nine'
    elif x == 2:
        y= 'Two'
    else :
        y= 1 
    return y


ddf['AndHSR'] = ddf.apply(f(ddf['Month']))

标签: pythonpandasconditional-statementsvectorizationdask

解决方案


您可以使用np.select矢量化方法。

import pandas as pd
import numpy as np

np.random.seed(500)

df = pd.DataFrame({"var1":np.random.randint(0,20,10000000),
                   "var2":np.random.randint(0,25,10000000)})

df["result"] = np.select([(df["var1"]==0)&(df["var2"]>10),
                          (df["var1"]==0)&(df["var2"]<10)],  #list of conditions
                         ["Situation 1", "Situation 2"],     #list of results
                         default="No situation")             #default if no match

print (df.groupby("result").count())

#
                     var1     var2
result                        
No situation  9520776  9520776
Situation 1    279471   279471
Situation 2    199753   199753

推荐阅读