Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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 分组数据帧上的高效操作_Python_Pandas - Fatal编程技术网

Python 分组数据帧上的高效操作

Python 分组数据帧上的高效操作,python,pandas,Python,Pandas,我有一个非常大的熊猫数据框架,我需要一个基于另一列的组内排序。我知道如何迭代组,对组执行操作,并将所有这些组合并回一个数据帧,但是这很慢,我觉得有更好的方法来实现这一点。这是输入和我想要的结果。输入: ID price 1 100.00 1 80.00 1 90.00 2 40.00 2 40.00 2 50.00 输出: ID price order 1 100.00 3 1 80.00 1 1 90.00 2 2 4

我有一个非常大的熊猫数据框架,我需要一个基于另一列的组内排序。我知道如何迭代组,对组执行操作,并将所有这些组合并回一个数据帧,但是这很慢,我觉得有更好的方法来实现这一点。这是输入和我想要的结果。输入:

ID   price
1    100.00
1    80.00
1    90.00
2    40.00
2    40.00
2    50.00
输出:

ID   price  order
1    100.00 3
1    80.00  1
1    90.00  2
2    40.00  1
2    40.00  2 (could be 1, doesn't matter too much)
2    50.00  3
由于这是超过5kk的记录,大约250000个ID,因此效率非常重要。

您可以使用:

在一个500万行、250000个ID(i5-3330)的数据集上大约需要30秒:

您可以使用:

在一个500万行、250000个ID(i5-3330)的数据集上大约需要30秒:


如果速度是您想要的,那么下面的内容应该很好,尽管它有点复杂,因为它在numpy中使用了复数排序。这类似于在包中编写聚合排序方法时使用的方法(MyMe)

在我的机器上,5万行需要2秒,这比使用pandas的
groupby.rank
快约100倍(虽然我没有实际运行5万行的pandas版本,因为这需要太长时间;我不确定@ayhan如何在30秒内做到这一点,也许pandas版本有所不同?)


如果您确实使用了它,那么我建议彻底测试它,因为我没有这样做

如果速度是您想要的,那么下面的内容应该很好,尽管它有点复杂,因为它在numpy中使用了复数排序。这类似于在包中编写聚合排序方法时使用的方法(MyMe)

在我的机器上,5万行需要2秒,这比使用pandas的
groupby.rank
快约100倍(虽然我没有实际运行5万行的pandas版本,因为这需要太长时间;我不确定@ayhan如何在30秒内做到这一点,也许pandas版本有所不同?)


如果您确实使用了它,那么我建议彻底测试它,因为我没有这样做

很可能@ayhan他的解决方案对我的用例来说已经足够了,但如果不足够,我将对此进行研究,谢谢!这实际上比排名快得多。顺便说一下,它给出了相同的结果。请注意,此方法假定ID为ints>=0,而不是过大。如果不是这种情况,则需要一些额外的工作或稍微不同的方法(但一般方法仍然有效)。很可能@ayhan他的解决方案对于我的用例来说已经足够了,但如果不是,我将对此进行研究,谢谢!这实际上比排名快得多。顺便说一下,它给出了相同的结果。请注意,此方法假定ID为ints>=0,而不是过大。如果情况并非如此,则需要一些额外的工作或稍微不同的方法(但一般方法仍然有效)。
df["order"] = df.groupby("ID")["price"].rank(method="first")
df
Out[47]: 
   ID  price  order
0   1  100.0    3.0
1   1   80.0    1.0
2   1   90.0    2.0
3   2   40.0    1.0
4   2   40.0    2.0
5   2   50.0    3.0
df = pd.DataFrame({"price": np.random.rand(5000000), "ID": np.random.choice(np.arange(250000), size = 5000000)})
%time df["order"] = df.groupby("ID")["price"].rank(method="first")
Wall time: 36.3 s
# get global sort order, for sorting by ID then price
full_idx = np.argsort(df['ID'] + 1j*df['price'])

# get min of full_idx for each ID (note that there are multiple ways of doing this)
n_for_id = np.bincount(df['ID'])
first_of_idx = np.cumsum(n_for_id)-n_for_id 

# subtract first_of_idx from full_idx
rank = np.empty(len(df),dtype=int)
rank[full_idx] = arange(len(df)) - first_of_idx[df['ID'][full_idx]]
df['rank'] = rank+1