Python 为每行计算子数据帧行的最有效方法?

Python 为每行计算子数据帧行的最有效方法?,python,pandas,dataframe,optimization,Python,Pandas,Dataframe,Optimization,假设我有一些熊猫数据框,它看起来像这样: creationDate 188080 2019-08-01 21:28:39+03:00 188081 2019-08-01 21:33:13+03:00 188082 2019-08-01 21:39:53+03:00 188083 2019-08-01 21:43:24+03:00 188084 2019-08-01 21:48:17+03:00 188085 2019-08-01 21:52:56+03:0

假设我有一些熊猫数据框,它看起来像这样:

                    creationDate
188080 2019-08-01 21:28:39+03:00
188081 2019-08-01 21:33:13+03:00
188082 2019-08-01 21:39:53+03:00
188083 2019-08-01 21:43:24+03:00
188084 2019-08-01 21:48:17+03:00
188085 2019-08-01 21:52:56+03:00
188086 2019-08-01 21:58:27+03:00
188087 2019-08-01 22:10:50+03:00
188088 2019-08-01 22:14:58+03:00
188089 2019-08-01 22:17:43+03:00
我想创建一个新列,名为
density
。对于每一行,它表示“当前单元格
creationDate
之后和当前单元格
creationDate
+
1小时之前有多少行”

我有一个矢量化函数,但在我的数据集(大约150万行)上,它的运行速度不是很快(在我的笔记本电脑上花了大约5分钟)

def get_density(日期、距离,以分钟为单位):
开始日期时间=日期
end_datetime=date+np.timedelta64(距离以分钟为单位,'m')
返回df.loc[
(df['creationDate']>=str(开始日期时间))和(df['creationDate']

如何优化此查询?提前谢谢

这似乎是使用
多处理.Pool
map
方法的一个很好的候选者。
get\u density
函数本质上就是worker函数

但是,辅助函数只获取一个参数,最好也为其提供对数据帧的引用。因此,在将结果用作辅助函数之前,请使用
functools.partial
提供
distance\u in\u minute
,并使用数据帧
get\u density


在最好的情况下,如果您的CPU有N个内核,这将使它大约快N倍。因此,如果您有一个4核CPU,时间应该从5分钟增加到大约1.25分钟。

使用Dask如何。它是一个python并行计算库,可以比纯python快得多

一些注释(很好拥有)-

1) 它不支持多重关联

2) 应为列指定适当的数据类型

从dask导入数据帧作为dd
从多处理导入cpu\u计数
作为pd进口熊猫
df=df.reset_index()
df.creationDate=pd.DataFrame(df.creationDate)
def获取密度(日期):
距离(单位:分钟)=60
开始日期时间=日期
end\u datetime=pd.to\u datetime(date)+np.timedelta64(距离以分钟为单位,'m')
返回(df.loc)[
(df['creationDate']>=str(开始日期时间))和(df['creationDate']
np.vectorize()
更好的解决方案是
df.apply
。 您可以尝试以下操作:

df['density']=(df.apply(lambda x: get_density(x.creationDate),axis=1))
一旦创建了带有
datetimeIndex
的系列,就可以使用时间。因为您希望在时间上向前看,所以在使用
[::-1]
反转列creationDate的顺序后,需要首先通过将每个日期和最大日期之间的时间增量添加到随机日期来反转索引的顺序。这里有一个方法:

df['density'] = (pd.Series(1, #create a Series with 1 as value but you can use anything
                                  # index need a start date, anyone is fine
                           index= pd.to_datetime("today") + 
                                  # time delta between each rows once reverse and the max
                               (df.creationDate.max() - df.creationDate[::-1]))
                   .rolling('20T') # with the given data, I use 20 minutes as interval,
                                   # change it to 1H for 1 hour, or 60T
                   .count() #count the number of rows within the rolling window
                   .values[::-1]) #reverse the values to come back to the original order
你得到了什么

print (df)
                    creationDate  density
188080 2019-08-01 21:28:39+03:00      5.0
188081 2019-08-01 21:33:13+03:00      5.0
188082 2019-08-01 21:39:53+03:00      5.0
188083 2019-08-01 21:43:24+03:00      4.0
188084 2019-08-01 21:48:17+03:00      3.0
188085 2019-08-01 21:52:56+03:00      3.0 #here you have 3 rows within 20 minutes
188086 2019-08-01 21:58:27+03:00      4.0
188087 2019-08-01 22:10:50+03:00      3.0
188088 2019-08-01 22:14:58+03:00      2.0
188089 2019-08-01 22:17:43+03:00      1.0