Python 熊猫在不同条件下执行操作-不同的方式和最佳实践?

Python 熊猫在不同条件下执行操作-不同的方式和最佳实践?,python,pandas,dataframe,Python,Pandas,Dataframe,我想根据一个值的条件在一个数据帧上运行多个不同的操作。 我有一些可行的解决方案,但它们似乎是使用熊猫的一种奇怪的方式,或者运行速度有点慢。 我相信这是一个共同的任务,所以我希望有一个“支持者”的方法来解决它。 因为我将不得不做很多像这样的事情,我想学习它 示例df: names = ['john doe', 'jane doe', 'jimmy - tables', 'bobby / tables'] condition_str = ['condition 1', 'condition 1',

我想根据一个值的条件在一个数据帧上运行多个不同的操作。 我有一些可行的解决方案,但它们似乎是使用熊猫的一种奇怪的方式,或者运行速度有点慢。 我相信这是一个共同的任务,所以我希望有一个“支持者”的方法来解决它。 因为我将不得不做很多像这样的事情,我想学习它

示例df:

names = ['john doe', 'jane doe', 'jimmy - tables', 'bobby / tables']
condition_str = ['condition 1', 'condition 1', 'condition 2', 'condition 3']
nums = [1, 2, 3, 4]
df_example = pd.DataFrame({'Name': names, 'Condition': condition_str, 'Numbers': nums})
我想基于一个或多个条件在不同的列上运行多个操作,并将其返回到不同的列。 在本例中,将名称拆分为不同的子字符串(“,-”),并将数字乘以不同的值

这是一个提供正确输出的函数:

def split_name_condition(row):
    if row['Condition'] == 'condition 1':
        first_name, last_name = row['Name'].split(' ')
        nums2 = row['Numbers'] * 2
        return [first_name, last_name, nums2]
    elif row['Condition'] == 'condition 2':
        nums2 = row['Numbers'] * 10
        first_name, last_name = row['Name'].split(' - ')
        return [first_name, last_name, nums2]
    else:  # needs explicit two return values for the append in iter_lists()
        return None, None, None
我可以使用apply运行它:

def run_apply(df):
    df[['first_name', 'last_name', 'Number2']] = df.apply(split_name_condition, axis=1, result_type='expand')
    return df
或使用iterrows:

def run_iter_lists(df):
    first_name, last_name, numbers2 = [], [], []
    for _, row in df.iterrows():
        f_name, l_name, nums2 = split_name_condition(row)
        first_name.append(f_name)
        last_name.append(l_name)
        numbers2.append(nums2)

    df_result = pd.DataFrame({'first_name': first_name,
                              'last_name': last_name,
                              'Numbers2': numbers2})
    return pd.concat([df, df_result], axis=1, sort=False)
对我来说,在DF上迭代似乎有点奇怪

使用布尔索引:

def run_bool_index(df):
    df.loc[df['Condition'] == 'condition 1', 'list_name'] = df['Name'].str.split(' ')
    df.loc[df['Condition'] == 'condition 2', 'list_name'] = df['Name'].str.split(' - ')
    df.loc[df['Condition'] == 'condition 3', 'list_name'] = df['Name'].str.split(' / ')

    df.loc[df['Condition'] == 'condition 1', 'Numbers2'] = df['Numbers']*2
    df.loc[df['Condition'] == 'condition 2', 'Numbers2'] = df['Numbers']*10

    df[['first_name', 'last_name']] = pd.DataFrame(df['list_name'].values.tolist())
    return df
在我看来,布尔指数更像是熊猫的预期用途,但与apply和ItErrors相比,它的速度非常慢

timeit在100次执行时产生的结果:

apply:
0.20913150000000025
iter_lists:
0.16314859999999998
bool_index:
0.7845151000000001
这类任务有什么通用解决方案或最佳做法吗?

您可以尝试以下方法:

def myfunc(df):
    df['list_name']=df['Name'].str.findall('\w+')
    df['Numbers2']=(np.select([df['Condition'].eq('condition 1'),df['Condition']
                          .eq('condition 2')],[df['Numbers']*2,df['Numbers']*10]))
    df[['first_name', 'last_name']]=df['Name'].str.extract('(\w+)\W+(\w+)')
    return df
您可以尝试以下方法:

def myfunc(df):
    df['list_name']=df['Name'].str.findall('\w+')
    df['Numbers2']=(np.select([df['Condition'].eq('condition 1'),df['Condition']
                          .eq('condition 2')],[df['Numbers']*2,df['Numbers']*10]))
    df[['first_name', 'last_name']]=df['Name'].str.extract('(\w+)\W+(\w+)')
    return df

编辑为我生成了一个keyerror:“``keyerror:”[Index(['first\u name','last\u name'],dtype='object')]中没有一个在[columns]中,``编辑之前的部分运行正常。np.select确实帮助了我。以我的例子来说,正则表达式搜索是聪明的,但我可能选择了一个糟糕的搜索。我必须在不同的列上使用几个不同的函数和操作,并根据一个列值作为条件返回多个coumn。因此,拆分只是我能想到的函数调用的一个例子。编辑为我生成了一个keyerror:``keyerror:“[Index(['first\u name','last\u name',dtype='object')]中没有一个在[columns]中”``编辑之前的部分运行正常。np.select确实帮助了我。以我的例子来说,正则表达式搜索是聪明的,但我可能选择了一个糟糕的搜索。我必须在不同的列上使用几个不同的函数和操作,并根据一个列值作为条件返回多个coumn。所以拆分只是我能想到的函数调用的一个例子。