Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何提高pandas中数据帧列映射函数的计算速度_Python_Dataframe - Fatal编程技术网

Python 如何提高pandas中数据帧列映射函数的计算速度

Python 如何提高pandas中数据帧列映射函数的计算速度,python,dataframe,Python,Dataframe,我正在基于整个数据帧中的其他值在数据帧中创建一个新列。我已经找到了几种方法(如下所示),但在处理大型数据集时,它们的速度非常慢(500k行需要1小时才能运行)。我希望提高这个过程的速度 我已尝试使用。与lambda函数一起应用。我还使用了.map来获取要放入新列的列表。这两种方法都有效,但速度太慢 values={'ID':['1'、'2'、'3'、'4'、'1'、'2'、'3'], ‘MOD’:[‘X’、‘Y’、‘Z’、‘X’、‘X’、‘Z’、‘Y’], ‘期间’:[‘当前’、‘当前’、‘当前

我正在基于整个数据帧中的其他值在数据帧中创建一个新列。我已经找到了几种方法(如下所示),但在处理大型数据集时,它们的速度非常慢(500k行需要1小时才能运行)。我希望提高这个过程的速度

我已尝试使用。与lambda函数一起应用。我还使用了.map来获取要放入新列的列表。这两种方法都有效,但速度太慢

values={'ID':['1'、'2'、'3'、'4'、'1'、'2'、'3'],
‘MOD’:[‘X’、‘Y’、‘Z’、‘X’、‘X’、‘Z’、‘Y’],
‘期间’:[‘当前’、‘当前’、‘当前’、‘当前’、‘过去’、‘过去’、‘过去’]
}
df=数据帧(值、列=['ID'、'MOD'、'Period'])
df['ID_MOD']=df['ID']+df['MOD']
定义函数(标识符、标识符、修改、期间):
如果期间==“当前”:
如果(df.ID==标识符).sum()==1:
返回“新”
elif(df.ID\u MOD==标识符\u修改)。sum()==1:
返回“唯一”
其他:
返回“重复”
其他:
返回“不适用”
初始df:

ID MOD Period ID\u MOD
0 1 X当前1X
1 2 Y电流2 Y
2 3Z电流3Z
3 4倍电流4倍
4 1乘以1
5 2 Z过2 Z
6年3月3日过去3年
以下是两种速度太慢的方法: (一)

df['new_column']=df.apply(λx:funct(x['ID'],x['ID_MOD'],x['Period']),轴=1)
(二)

df['new_column']=list(map(函数,df['ID'],df['ID_MOD'],df['Period']))
预期最终df:

ID MOD Period ID\u MOD new\u列
0 1 X当前1X重复
1 2 Y电流2 Y唯一
2 3 Z电流3 Z唯一
3 4 X当前4 X新
4 1倍过去1倍不适用
5 2 Z过2 Z不适用
6 3年过去3年不适用

没有错误消息;使用大数据集运行代码只需约1小时。

您当前的代码当前按O(N**2)缩放,其中N是行数。如果您的
df
确实是500k行,这将需要很长时间!您确实希望使用numpy和pandas提供的代码,这些代码的计算复杂度要低得多

内置的pandas将有助于取代您使用的
sum
,学习pandas如何编制索引和索引。在你的情况下,我可以很容易地将500k行减少到不到一秒钟

首先定义一个虚拟数据集:

import numpy as np
import pandas as pd

N = 500_000

df = pd.DataFrame({
    'id': np.random.choice(N//2, N),
    'a': np.random.choice(list('XYZ'), N),
    'b': np.random.choice(list('CP'), N),
})
接下来,我们可以对您的各个组进行聚合计数:

ids = df.groupby(['id']).size().rename('ids')
idas = df.groupby(['id','a']).size().rename('idas')
接下来,我们可以将这些聚合连接回原始数据集

尽可能减少数据总是一个好主意,在您的情况下,
过去的
值总是得到一个
n/a
的值,因为它们占据了一半的数据,您的工作量似乎只有一半:

df2 = df.loc[df['b'] == 'C',]
df2 = pd.merge(df2, ids, left_on=['id'], right_index=True)
df2 = pd.merge(df2, idas, left_on=['id','a'], right_index=True)
最后,我们使用numpy中的
where
对所有条件进行矢量化,从而更快地工作,然后使用pandas索引将所有内容有效地重新组合在一起,随后修补缺失的值

df2['out'] = np.where(
    df2['ids'] == 1, 'New',
    np.where(df2['idas'] == 1, 'Unique', 'Repeat'))

df['out'] = df2['out']
df['out'].fillna('n/a', inplace=True)

希望这能有所帮助!作为参考,我的笔记本电脑上500k行的上述数据运行时间约为320ms

如果计算可以并行化,也许你应该试试?