Python 快速排序和附加大型数据帧的方法
我试图对每个产品销售日和产品ID的一些销售数据进行排序,然后我想用熊猫计算一些统计数据。有没有一种有效的方法可以做到这一点?我的数据集有数百万行 数据集看起来像df1,3.000.000+行:------------------------------------Python 快速排序和附加大型数据帧的方法,python,pandas,numpy,Python,Pandas,Numpy,我试图对每个产品销售日和产品ID的一些销售数据进行排序,然后我想用熊猫计算一些统计数据。有没有一种有效的方法可以做到这一点?我的数据集有数百万行 数据集看起来像df1,3.000.000+行:------------------------------------ |productID |productCategory |expiryDate |Price |Currency |quantitySold| daySold| |Fdgd4 |Ergdgf |15sep2020 00:00:
|productID |productCategory |expiryDate |Price |Currency |quantitySold| daySold|
|Fdgd4 |Ergdgf |15sep2020 00:00:00 |125 |USD |5675 |18feb2017 12:45:17|
|Sd23454 |sdfdsr |17mar2018 00:00:00 |39 |USD |654 |31jan2017 12:45:17|
|Fdgd4 |Ergdgf |15sep2020 00:00:00 |125 |USD |300 |18feb2017 09:17:15|
|Sd23454 |sdfdsr |17mar2018 00:00:00 |39 |USD |200 |31jan2017 15:30:35|
|Rt4564 |fdgdf |13jun2018 00:00:00 |45 |USD |1544 |31feb2017 13:25:31|
|Fdgd4 |Ergdgf |15sep2020 00:00:00 |125 |USD |4487 |18mar2017 09:17:15|
|Sd23454 |sdfdsr |17mar2018 00:00:00 |39 |USD |7895 |31aug2017 15:30:35|
我想每天按productID排序并计算一些简单的统计数据。因此,我认为我的代码应该首先按天排序,然后按产品排序。然后它应该计算统计数据并将它们添加到表中
本例中的结果为isdf2:
|productID |productCategory |expiryDate |Price |Currency |quantitySold |daySold |volSTD |totalVol |totalRevenue|
------------------------------------------------------------------------**
|Sd23454 |sdfdsr |17mar2018 00:00:00 39 |USD |654 |31jan2017 12:45:17 |321.02 |854 |33306 |
|Fdgd4 |Ergdgf |15sep2020 00:00:00 125 |USD |300 |31jan2017 15:30:35 |0 |300 |37500 |
|Fdgd4 |Ergdgf |15sep2020 00:00:00 125 |USD |5675 |18feb2017 12:45:17 |840.04 |10162 |1270250|
|Rt4564 |fdgdf |13jun2018 00:00:00 45 |USD |1544 |31feb2017 13:25:31 |0 |544 |69480 |
|Sd23454 |sdfdsr |17mar2018 00:00:00 39 |USD |7895 |31aug2017 15:30:35 |0 |7895 |307905 |
我在pandas中使用了嵌套的for循环,它给出了预期的结果,但它确实需要花费几个小时的时间。
我正在寻找一种快速的方法来获得这个结果
我的代码可能是您见过的最糟糕的代码之一:
uniqueDays = df1.daySold.unique()
numberOfDays = df1.shape[0]
df_results = pd.Dataframe(columns=[‘productID’, ‘productCategory’, ‘expiryDate Price’, ‘Currency’, ‘quantitySold’, ‘daySold’, ‘volSTD’, ‘totalVol’, ‘totalRevenue’])
For i in range(0, numberOfDays):
temp1 = df1.loc[df1[‘daySold’]== uniqueDays[i]]
uniqueID = temp1.productID.unique()
NumberOfUniqueID = uniqueID.shape[0]
for j in range(0, NumberOfUniqueID):
temp2 = temp1.loc[temp1[‘daySold’]== uniqueID[j]
volSTD = temp2.quantitySold.std()
totalVol = temp2.quantitySold.sum()
totalRevenue = temp2.quantitySold.dot(temp2.price)
temp3 = temp2.iloc[0] # it does not matter which row I pick
temp3[‘volSTD’] = volSTD
temp3[‘totalVol’] = totalVol
temp3[‘totalRevenue’] = totalRevenue
df_results = df_results.append(temp3)
这给了我想要的结果,但它太慢了。特别是将volSTD、totalVol和totalRevenue列添加到temp3,并将temp3添加到df_结果,总共需要81.3%的处理时间
有没有人有更快的方法?使用向量?或者填充现有数据帧而不是追加
谢谢你,groupby怎么样?可以说,它比循环更有效地处理迭代,并且代码更短、可读性更好。您将在Daysald和productID上分组。这显然是模拟数据,但您可能希望首先将Daysald转换为datetime对象,以便可以轻松地对其进行分组-我只保留了一天,但如果需要,您可以保留时间:
df.daySold=pd.to_datetime(df.daySold.apply(lambda x: x[:9]),format="%d%b%Y")
那么它只是一个班轮。使用groupby对象,您可以传递许多不同的聚合调用
df.groupby(['daySold','productID']).agg({'quantitySold':[sum,np.std],'Price':[sum,np.std]})
quantitySold Price
sum std sum std
daySold productID
2017-01-31 Sd23454 854 321.026479 78 0.0
2017-02-13 Rt4564 1544 NaN 45 NaN
2017-02-18 Fdgd4 5975 3800.698949 250 0.0
2017-03-18 Fdgd4 4487 NaN 125 NaN
2017-08-30 Sd23454 7895 NaN 39 NaN
编辑:
您可以使用groupby对象应用所有类型的函数,包括现成函数和您自己定义的函数
所以你可以做点积,需要一个数据帧的两列/数组,如下所示:
def dotter(df):
return np.sum(df.quantitySold*df.Price)
## or if you want to use numpy--may be faster for large datasets:
#return np.dot(df.quantitySold,df.Price)
使用groupby对象的apply方法调用它:
df.groupby(['daySold','productID']).apply(dotter)
daySold productID
2017-01-31 Sd23454 33306
2017-02-13 Rt4564 69480
2017-02-18 Fdgd4 746875
2017-03-18 Fdgd4 560875
2017-08-30 Sd23454 307905
dtype: int64
你看过groupby吗?这听起来像是一个清晰的groupby工作流。谢谢,您的解决方案要快得多。只有我如何计算groupby中卖出的价格和数量之间的点乘?如何返回其他列ProductID | productCategory | expiryDate | Price | Currency | QuantitySeld | Daysaled?对于第二个问题,我只得到了sum和std.Thanks-如果其他列随productID唯一变化,您可以将它们添加到groupby子句中,然后它们将成为多重索引的一部分。非常感谢!我在用index=False向csv写入数据,没有意识到丢失的列实际上就是索引。最后一个细节:是否可以在agg中调用dotter函数?如果不是,我将不得不连接两个数据帧。再次感谢