语法结构
apply函数是`pandas`里面所有函数中自由度最高的函数。使用时,通常放入一个lambda函数表达式、或一个函数作为操作运算,官方上给出DataFrame的apply()用法:
DataFrame.apply(self, func, axis=0, raw=False, result_type=None, args=(), **kwargs)
参数:
func: 函数或 lambda 表达式,应用于每行或者每列
axis: {0 or "index", 1 or "columns"}, 默认为0
0 or "index": 表示函数处理的是每一列
1 or "columns": 表示函数处理的是每一行
raw: bool 类型,默认为 False;
False,表示把每一行或列作为 Series 传入函数中;
True,表示接受的是 ndarray 数据类型;
result_type: {"expand", "reduce", "broadcast", None}, default None
These only act when axis=1 (columns):
"expand": 列表式的结果将被转化为列。
"reduce": 如果可能的话,返回一个 Series,而不是展开类似列表的结果。这与 expand 相反。
"broadcast": 结果将被广播到 DataFrame 的原始形状,原始索引和列将被保留。
args: func 的位置参数
**kwargs: 要作为关键字参数传递给 func 的其他关键字参数,1.3.0 开始支持
返回值:
Series 或者 DataFrame:沿数据的给定轴应用 func 的结果
使用案例-DataFrame使用apply
该数据集有一千条数据,类型为DataFrame。
我们将neirong字段使用jieba进行分词、获取词性,写入新的字段segmentation
自定义函数处理
1、定义一个功能函数,用来切词。
def tokenize_text(sent):
data = posseg.lcut(sent)
data = [
(_.word, _.flag[:1]) for _ in data
]
return data
2、用apply方法调用tokenze_text函数
%%time
df['segmentation']= df.neirong.apply(tokenize_text)
3、执行结果展示
可以看到segmentation 已经分词完成,词性也对应上了,通过上面这种方案处理1000条数据用了8.41秒。
lambda函数处理
1、用apply方法调用lambda函数
%%time
df['segmentation'] = df.neirong.apply(lambda x: [(_.word, _.flag[:1]) for _ in posseg.lcut(x)])
2、执行结果展示
可以看到segmentation 已经分词完成,词性也对应上了,通过上面这种方案处理1000条数据用了8.08秒。
Apply Multiprocessing
Apply Multiprocessing
通过上面的使用案例我们已经大概知道apply在日常开发中如何使用了,但上面1000条数据处理时长就8秒左右,那一万条岂不是更多。
在处理大量数据时,如果只是使用单线程的 apply() 函数,速度可能会很慢。这时,可以考虑使用多进程来加速处理。使用多进程可以同时处理多个任务,提高数据处理的效率。
定义多进程apply函数
def apply_parallel(df, func, num_processes):
pool = mp.Pool(num_processes)
results = pool.map(func, [df.iloc[i].neirong for i in range(df.shape[0])])
pool.close()
pool.join()
return results
在上述示例代码中,apply_parallel() 函数中使用了 Python 内置的 multiprocessing 模块创建了一个进程池,并将每一行数据都传递给一个函数进行处理。在这个函数中,将 DataFrame 的neirong进行分词,然后将结果保存到新的列表中。
调用执行
%%time
df['segmentation'] = apply_parallel(df, tokenize_text, 8)
结果展示
可以看到segmentation 已经分词完成,词性也对应上了,通过上面这种方案处理1000条数据用了2.42秒。处理的数据越多,差异越明显。
需要注意的是,使用多进程处理数据时,可能会出现数据不一致的问题,需要进行一定的控制和同步。另外,多进程处理数据也会消耗更多的系统资源,需要根据具体情况进行权衡和优化。